I've stored my credentials in the KeyChain in the Login.m class
[SFHFKeyChainUtils storeUsername:self.usernameField.text andPassword:self.passwordField.text forServiceName:#"myApp" updateExisting:TRUE error:&error];
Now when i delete from memory my app from my iPhone and start it again, if the user has logged in before, i want the login screen to be skipped and next screen to be shown.
Now my question is, how to do that in AppDelegate.m class. I want to access the current user's credentials and if they are filled with data, login screen to be skipped.
[SFHFKeyChainUtils getPasswordForUsername:??? andServiceName:#"myApp" error:&error];
I know that this is the way if getting the password for a given username, but the problem is that i dont have the access to the username in the AppDelegate class.
Can someone help me?
Thank you :)
I've found a solution using NSUserDefaults, storing username and password for later use, but on several posts i've read that using SFHFKeyChainUtils is more secure than NSUserDefaults.
Related
I'd like to use an auto-login function. So when the user opens the app, he gets delegated to a "login screen". When he logged in successfully he should be directed to his account. I call this the "account screen". Now when the user restarts the app, he should directly get directed to his account, without seeing the "login screen".
The login function already works fine in my project (username and password are saved in UserDefault), but every time I close the app, I have to login again. So my question is: How do auto login the user? Or better said: How do I check if the data (saved in UserDefault) is the same as in the database (MYSQL)?
For the first time when the user login, you save the user
credentials in iPhone's keychain.
When the app is opened again, you check whether user credentials are
present in keychain and if yes, you code should call the login
logic and do auto login and go to screen after login screen. If no,
then you should show login screen. You can do this logic in AppDelegates applicationDidFinishLaunching.
Whenever user clicks the logout button, remove user credentials from
keychain first, and go back to login controller.
Simply you add login credentials to keychain when user logs in and only remove it once user clicks the logout button. If user quits the app without logout then the credentials will still be in keychain and you can retrieve them when user returns to the app.
EDIT: I think I must add one more thing..If your login logic takes time (like you login using web request or something), put the login logic code in your Login ViewController rather than ApplicationDelegate, and use any Activity Indicator during auto login process.
EDIT : I edited the entire answer, replaced NSUserDefault with Keychain. This thread explains why.
While saving Username and Password, it is highly advised to save in Keychain rather than the NSUserDefaults. Refer this post for a better understanding.
To answer the question: if you want to auto-login with keychain data, use the free framework "SFHFKeychainUtils". It saves username, password and servicename in keychain. if you want to retrieve it, just save the username in NSUserDefaults and you can get the password with ease.
Here we go:
SiFi HiFi Framework: https://github.com/ldandersen/scifihifi-iphone/tree/master/security
SiFi Hifi Framework (ARC compatible): https://stackoverflow.com/a/10348964/1011125
How to use SFHFKeychainUtils: http://gorgando.com/blog/technology/iphone_development/simple-iphone-tutorial-password-management-using-the-keychain-by-using-sfhfkeychainutils
I used a combination of NSUserDefaults and SSKeychain. I used NSUserDefaults to store the username nad SSKeychain to store the password.
This is the code I used to save the credentials
NSString *user = self.username.text;
NSString *password = self.pass.text;
[SSKeychain setPassword:password forService:#"achat" account:user];
NSUserDefaults *dUser = [NSUserDefaults standardUserDefaults];
[dUser setObject:user forKey:#"user"];
[dUser synchronize];
This is the code I used to retrieve the credentials
NSUserDefaults *eUser = [NSUserDefaults standardUserDefaults];
NSString *savedUser = [eUser objectForKey:#"user"];
if (!savedUser) {
UIAlertView *uhoh = [[UIAlertView alloc] initWithTitle:#"Oops!" message:#"Please enter your username and password." delegate:self cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil];
[uhoh show];
}
else {
NSString *savedPass = [SSKeychain passwordForService:#"achat" account:savedUser];
self.username.text = savedUser;
self.pass.text = savedPass;
}
At first of all i want to say that i am newer as an iPhone application developer.So please help me. Now, My problem is, I want to make a text file in my iPhone app.If I explain it then I will say that...
When user will login in my app then he/she will give username and password, Now i want to store these data in the text file and text file will store in the documentsDirectory, when this user again lunch the application then automatically he will able to excess the app without any authentication checking if he/she does not logout from the application first time.
1) 1st person --> login [username & password] --> store username and pass into text file because new user --> enjoy application -->logout.
2) 2nd person --> login [username & password] --> store in text file into text file because new user --> enjoy application --> did not logout.
3) 2nd person again ---> will not give username and password directly he/she have to use the application -->logout.
4) 1st person now ---> login [username & password] and check by saved reading text file ---> enjoy application --> logout.
5) 2nd person now ---> login [username & password] and check by saved reading text file ---> enjoy application --> logout.
Now, my question is how can i do this full process.Can i do this using NSUserDefaults standardUserDefualts or i need to make a text file for storing username & password??
Yes you can store simple bits of data like these in standardUserDefaults.
I assume that you will check user identity though.
e.g.what if user 1 logs in but does not logout and then user2 launches the app?
Personally I would only store the username if you plan for more than one person to access the app on a specific device and I would require the password each time.
set:
[[NSUserDefaults standardUserDefaults] setObject:userNameStr forKey:userName];
[[NSUserDefaults standardUserDefaults] synchronize];
get:
userNameStr = [[NSUserDefaults standardUserDefaults] objectForKey:userName];
I would think about storing username/password in the keychain. It is more secure and you won't have to worry about that information getting hacked out of the user defaults plist. If you still want to use a username and password, consider hashing it before storing it. Then if that information gets out (unlikely, but still possible) it won't mean anything to them.
You can actually view the contents of your user defaults from Organizer, the information is just stored as plain text there, so it is not recommended to use this as a way to store username and password.
I don't get it with the Dropbox API.
I got an app with CoreData. The user can choose if he wants to upload the SQlite file to Dropbox. So i made a settings tab where he can de-/activate the Dropbox sync and enter Dropbox username and password. (Yes, I know that Dropbox doesn't want to store the password).
The SQLite file should be uploaded, if the user changes anything.
So I don't need an ViewController for Dropbox functions.
What I want is something like a DropboxHelper class (NSObject), with a function like
+ (void)uploadFile;
In my Dropbox account, I created an App. The App Key and App Secret I use in my AppDelegate:
DBSession* session = [[[DBSession alloc] initWithConsumerKey:#"KEY"consumerSecret:#"SECRET"]autorelease]; <br>
[DBSession setSharedSession:session];
[session release];
For the upload I need a DBRestClient. In my upload function I test if the session is linked. If not, login the user:
if (![[DBSession sharedSession]isLinked]) {
[self.restClient loginWithEmail:#"USERNAME"
password:#"PASSWORD";
}
But the session is always linked?! And I have to init the DBRestClient like this:
restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
So what I don't get:
I need the APP KEY and APP SECRET to use the API (so its the API Key)?
How do I login the User if the session is already linked? (I don't want to use the DBLoginController for login)
If I don't init the session in AppDelegate, how can I init the DBRestClient with a session?
Is it generally possible to use the API like this? Without a Viewcontroller and use NSObject instead?
https://www.dropbox.com/developers/reference/bestpractice covers this.
Never handle user login and password information. All application authentication is done using tokens exchanged via the Dropbox mobile app or website and the methods described in the authentication tutorial.
Another way to say this is that Dropbox does not want to put users in the position of trusting an app developer with their passwords.
I've done a lot of reading of the Facebook docs, but I'm pretty confused about the role of the session object. For instance, with the method:
session = [FBSession sessionForApplication:myApiKey secret:myAppSecret delegate:self];
What am I supposed to do with the session object that's returned to me, when presumably I need to wait for the delegate callback in order to do anything?
Secondly...upon a later execution of my app, when the user has authorized me accessing their account during a previous execution, how do I get a reference to a session object so I can connect to their Facebook account and post status, etc.? The docs mention [session resume], but don't say where that session reference is supposed to come from. (And calling [[FBSession session] resume] compiles, but doesn't work.)
Thanks.
What am I supposed to do with the session object that's returned to me, when presumably I need to wait for the delegate callback in order to do anything?
You have to create and show a FBLoginDialog to the user. The delegate method will not be called until the user has logged in. It has nothing to do with creating the session instance in the first place.
how do I get a reference to a session object so I can connect to their Facebook account
The Facebook Connect library will store the session info in your app's user defaults. You don't have to do anything to store it. As I understand it, on every launch of your app you should create the session object with +sessionForApplication:secret:delegate: and then call [session resume]. If the FBConnect library finds a valid session stored in the user defaults, it will return YES and you can proceed as the user is now logged in. If resume returns NO, you will have to show the login dialog.
From Facebook's docs:
The session information will be stored on the iPhone disk in your application's preferences, so you won't have to ask the user to log in every time they use your application. After you've created your session object, call [session resume] to resume a previous session. If the session has expired or you have yet to create a session, it will return NO and you will have to ask your user to log in. Sessions expire after two hours of inactivity.
this is really following on from Ole's answer and comments as it is all in there. This is what I did.
Firstly create the session object:
facebookSession = [[FBSession sessionForApplication:SESSION secret:SECRET delegate:self]retain];
[facebookSession resume];
The second line pulls the session data from the settings file to keep you logged on if the user specifies that they'd like to be kept logged on.
You have to implement the method:
- (void)session:(FBSession*)session didLogin:(FBUID)uid
although I don't use it for anything.
To check if the user is already logged on, I call:
[[FBSession session] isConnected]
and then either display the login dialog or straight to the publish dialog if they are already logged on.
Hey, I am using facebook connect sdk for iPhone, every time I start my app and click login, there would be a login screen asking me to input my name and password.
Is there any way to keep me logged in once I input my name and password, that's to say, I needn't to input my name and password again the next time I start my app?
According to the Platform Guidelines 1.3, you are not allowed to store a Facebook user's credentials. The best you can hope for is that your user checks the "Keep me logged in" option. She should be able to post without having to login any time soon, even if she restarts your app.
The following snippet works with the above scenario:
NSString *fbAPIKey = ...;
NSString *fbApplicationSecret = ...;
_session = [[FBSession sessionForApplication:fbAPIKey secret:fbApplicationSecret delegate:self] retain];
// checks whether session can be resumed - whether login is required
if (![_session resume]) {
FBLoginDialog *loginDialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[loginDialog show];
}
Store the password (or the requisite hash of it) somewhere.
You need to use the keychain. Have a look to this article: http://log.scifihifi.com/post/55837387/simple-iphone-keychain-code