views:

153

answers:

3

On iPhone, how do I show a login screen to get username and password before giving access to iPhone app? Also, does the iPhone store a cookie to the secure website like a web browser?

I was thinking of giving users to my website a long API key to store in the settings of their iPhone instead of asking them to login with a username/password (seems to be the Slicehost iPhone app approach.) Which is the best way to get a user to login securely? I have full control over the design of the iPhone app and website so have a lot of flexibility.

A: 

I'd recommend looking at a technology such as OAuth (http://oauth.net/). This enables the user to authorize access to their account to an application without having to actually enter their username and password into it. Also means you dont have to worry about secure storage of the users credentials, and if their passwords change etc it doesn't matter.

It's used by facebook / twitter and a lot of other big name companies so its not going away (Its actually in the process of getting approved as an offical standard).

RM
This is a little off topic from my question.
MikeN
@MikeN - How is that off topic? (and down vote?) You said your "thinking of giving users to my website a long API key to store in the settings of their iPhone". This is pretty similar to OAuth, why would you make your own method of security when you can use an existing standard? If you want to open the API up in the future, why make developers have to work out yet another authentication mechanism.
RM
A: 

You can't restrict access to the app itself but it is trivial to present an initial view that ask for the username and password. If the user does not present the correct information then the app will not allow them to progress to the next view which actually loads the web site.

Likewise, it would be trivial to store a key in the app's sandboxed folders such that neither the user nor anyone else could access it save through the app.

TechZen
+1  A: 

I have this need in a couple of apps, and I use the following pattern:

In the controller for the first view that gets presented to the user, I have the following test, where UserPrefsManager is a singleton that knows the user credentials. This call causes a modal view to appear (FirstTimeWelcomeViewController) which tells the person that they need to register.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UserPrefsManager * prefs = [UserPrefsManager sharedInstance];
    if (![prefs isLoggedIn])
    {
        FirstTimeWelcomeViewController * vc = [[[FirstTimeWelcomeViewController alloc] initWithNibName:@"FirstTimeWelcomeViewController" bundle:nil] autorelease];
        [self presentModalViewController:vc animated: false];
    }
    else 
    {
        if (![[RWXLocationSingleton sharedInstance] hasLocation]) {
            [[RWXLocationSingleton  sharedInstance] findLocationWithAccuracy:kCLLocationAccuracyThreeKilometers withObject:self andSelector:@selector(updateLocationsView)];
        }
        [[self tableView ]reloadData];
    }
}

FirstTimeWelcomeViewController is basically a screen with buttons that greets people and takes them to the various ways to log in:

-(IBAction) createAccount
{       
    UIViewController * parent = [self parentViewController];
    CreateAccountViewController * vc = [[[CreateAccountViewController alloc] initWithNibName:@"CreateAccountViewController" bundle:nil] autorelease];
    [self dismissModalViewControllerAnimated:false];
    [parent presentModalViewController:vc animated: false];
}

imagine that these also exist for forgotPassword, and loginACcount... same pattern. This causes the current view to be replaced by a view handling the specific case that they've pressed the button for.

taking the 'loginAccount' method, you've opened the LoginAccountViewController, and it has a method called loginButton, which works something like this...

-(IBAction) loginButton
{
    NSString * u = [self.username text];
    NSString * p = [self.password text];

        //
        // app specific logic that tests various inputs and creates a user object.
        //
        // goes here...
        //

        if([user checkValid])
    {
       UserPrefsManager * prefs = [UserPrefsManager sharedInstance];
       [prefs setPassword:p];
       [prefs setUsername:u];
       [self dismissModalViewControllerAnimated:FALSE];
    }
        //
        // more app specific stuff
        //
}

And that's pretty much that. You have to use one of the standard ways for putting stuff in the keychain or user defaults to save your information. check that the one you pick lasts between restores if it is something that is annoying for the user to recreate. The first part is the most useful bit, thought the rest might be useful for context.

corprew
note that this doesn't answer the second part of your question, just the first on how to present the dialog. For the first, i just ask them for an email to log into the app (username is actually email address, unhelpfully) and then let them choose a passord.
corprew
Thanks for the great answer! I used the NSUserDefaults to store the login information since it would persist and seemed a bit esaier to start.
MikeN
My App loads my 1st modal via the app delegate, should I remove that and place this in my First View of my tab controller or can this be placed in the AppDelegate.m?
Michael Robinson