How do I design and implement password authentication for IOS? - iphone

I have what seems to be a simple issue but I can't find a solution. I have spent hours trying to find an example that shows how to build a view, allow a user to enter a password, authenticate the password and return the view to a designated view. I have found a lot a great resources on bits and pieces, but they all are somewhat vague on how to authenticate the password and then send the user to a designated view.
This seems to be the best solution to my problem, which is: I have several pdfs that I need to password protect in my iPad app.

Issue1: Prompt for userName and Password
Present a view modally. if username/password combination is correct, dismiss the modal view. alternatively, you can use an alert with textfields.
Issue2: Store username/password in a secure way
Use key chain as suggested in the other answer. USage of key chain is as simple as using NSUserDefaults with Carlbrown's PDKeychainBindingsController. You can find it at the below link
https://github.com/carlbrown/PDKeychainBindingsController
EDITED to add info requested in comment:
Assuming you are using a custom view controller for login prompt, you have to do something like this when you want to prompt for password. it can be in your application didFinishLaunchingWithOptions.
LoginViewController *controller = [LoginViewController alloc];
[self presentModalViewController:controller animated:YES];
[controller release];
Then in your LoginViewController, you have to do something like this.
PDKeychainBindings *keyChain =[PDKeychainBindings sharedKeychainBindings];
if ([[keyChain objectForKey:#"User Name"] isEqualToString:userName] && [[keyChain objectForKey:#"Password"] isEqualToString:passWord] ) {
[self dismissModalViewControllerAnimated:YES];
}else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"ERROR" message:#"Wrong User Name and/or Password\nEnter Login Information Again"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
Please note that the strings userName and PassWord are captured from your textfields in login view controller.

In anticipation of your answer to my comment--
If you want the password to be stored locally, I would store it (hashed or otherwise) in the Keychain, to compare against the user-entered password. More in the Apple docs here.
I'd recommend downloading the Apple sample project for an example of storing/retrieving data from the keychain.

Oliver over at Cocoanetics.com has a very nice implementation of the security login screen apple uses. Look at the PinLockController class in MyAppSales.
https://github.com/Cocoanetics/MyAppSales
For keychain storage I use SFHFKeychainUtils. Its a simple method call to store and retrieve secure passwords. But I think standard NSUserDefaults would be sufficient for your needs.
(handy site http://gorgando.com/blog/tag/sfhfkeychainutils)

However, if you want to sell that app, keep in mind, that apple says
The user can set a four-digit personal identification number (PIN) to
prevent unauthorized use of the device, so there is no need for the
user to be authenticated and there are no authentication or
authorization APIs in iPhone OS.
This can be found in the Security Coding How-To's

Related

How to implement twitter login functionality on iPhone

I've already tried to use Facebook login functionality. During the login I got user token and using this token I could identify user. So, Facebook is OK for me.
1) How can I implement login functionality with Twitter? Will I get anything the same like user token on Facebook?
As far as I know, to use twitter API user should be login in twitter in the settings of iPhone. Can I implement anything to enable user to login even he is not yet logged in in the settings of iPhone?
2) After user login I want him to invite his twitter friends to my application. Is it possible to do? And in what ways?
I will be grateful for some code examples.
Please check the link below each and every step is clearly told by Twitter itself.
https://dev.twitter.com/docs/ios
If you still having problem please follow the link
http://www.raywenderlich.com/5519/beginning-twitter-in-ios-5
That contains the code and all steps !
Hope it will help you !
Please go through this link
it will provide stepwise details.
add
#import <Twitter/Twitter.h>
Then you can tweet something using:
-(IBAction)tweetTapped:(id)sender {
{
if ([TWTweetComposeViewController canSendTweet])
{
TWTweetComposeViewController *tweetSheet =
[[TWTweetComposeViewController alloc] init];
[tweetSheet setInitialText:
#"Tweeting from iOS 5 By Tutorials! :)"];
[self presentModalViewController:tweetSheet animated:YES];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Sorry"
message:#"You can't send a tweet right now, make sure
your device has an internet connection and you have
at least one Twitter account setup"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}

Undeclared identifier that is declared?

I am making an app where if the webpage doesnt load, it gives an error and returns to the previous screen. However, in doing this, after all the code, get an undeclared identifier
#pragma mark - View lifecycle
- (void)viewDidLoad
{
UIAlertView *cats = [[UIAlertView alloc] initWithTitle:#"**Read this first!**"
message:#"Thank you for ..."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[cats show];
[catscroll setScrollEnabled:YES];
[catscroll setContentSize:CGSizeMake(320,4800)];
[catscroll setPagingEnabled:NO];
[catform loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://m.petfinder.com/s/showPage.do?siteId=76333&pageId=7133416&shelterId=MA84&navigateToPage=Adopt%20Pets"]]];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)doPop
{
[cats dissmissWithClickedButtonIndex:-1 animated:YES];
[self.navigationController popViewControllerAnimated:YES];
UIAlertView *noconnectcatform = [[UIAlertView alloc] initWithTitle:#"Check your connection!"
message:#"Cannot connect to FPP Servers.\nPlease check your Internet Connection\nYou may not proceed until you are connected via a cellular network."
delegate:nil cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[noconnectcatform show];
}
as you can see in this image. If the webpage doesnt load it activates doPop, which returns the view and displays a message. However, this is throwing an EXC_BAD_ACCESS because, as you can see, under the viewDidLoad method, there is another message that plays. The app is getting confused and crashing. I tried to fix this by dismissing the alert in the doPop method, however it is strangely giving me this error. I may be misunderstanding, but isn't the alertview defined where it says "UIAlertView *cats"? why does it say that it is not defined in the doPop method? Please help!
The object cats is defined locally to viewDidLoad. The scope of the variable does not extend beyond the method, thus doPop has no idea what cats is.
Move cats to be defined in the .h file as a member/class variable.
This means you'll need to remove the UIAlertView * from within viewDidLoad and just reference cats (as is, you are defining another variable scoped to viewDidLoad).
You have a typo in the method called in doPop The method is dismissWithClickedButtonIndex:1 animated:YES]; You have dissmissWithClickedButtonIndex:1 animated:YES];
Also, you only need IBOutlet defined with the #property
Okay, so if i were you i would simply show the error message on the view that failed to load, then use the default cancel action to pop this view (This is the most common practice)
Alternatively, if you really wanna show the message in the other view you have to make that view display the error message. there are several ways to do this but id still go with the first option. (I could tell you how if you really wanna take this approach)
Edit: If you just want that error to go away, add before "Implementation" in your .m file
#interface CatForm ()
{
UIAlertView *cats;
}
#end
and change
UIAlertView *cats = [[UIAlertView alloc] initWithTitle:#"**Read this first!**"
message:#"Thank you for considering to adopt a cat from our shelter. PLEASE READ THIS FORM CAREFULLY.\n\nThis on-line form is intended to assist you in selecting a cat that is suitable for you, your family, and your lifestyle.\n\nThe Friends of the Plymouth Pound have established guidelines and policies that must be met in order for your pre-screening application to be approved.\n\nThe information you provide is essential to facilitate the application review process.\n\nIn order to be considered for adoption by the Friends of the Plymouth Pound, you must:\n\n\n*Be at least 18 years old.\n\n*Provide all the applicable information requested below.\n\n**Note, any data field marked with an asterisk character (*) must be filled in. Incomplete application forms will not be considered for review and will be denied automatically.**\n\n*Understand that this is a pre-screening form.\n\n\nThe Friends of the Plymouth Pound will contact you and approve you if, and only if, all requirements have been met.\n\nUpon review of your pre-screening application, you will be contacted by the Friends of the Plymouth Pound to notify you if your application has been accepted and if further information is needed. \n\n\n**Please note that we do contact all personal references and veterinarians, and we must speak with them personally. In addition, in some cases, a pre-adoption home visit may also be required.**\n\nIn the event that your pre-screening application has been not been approved, we will notify you of same.\n\n\nTHE BOARD OF DIRECTORS OF THE FRIENDS OF THE PLYMOUTH POUND RESERVES THE RIGHT TO DENY ANY PRE-APPLICATION BASED ON THE ORGANIZATION'S ESTABLISHED STANDARDS AND POLICIES, INCLUDING, BUT NOT LIMITED TO, INCOMPLETE INFORMATION, NON-DISCLOSURE OR OMISSION OF PERTINENT FACTS, AND NON-COMPLIANCE WITH ACCEPTED STANDARDS.\n\n\nUpon approval of your application and transfer of the animal, you will be charged a $150.00 adoption fee per cat.\n\n\nWe are an all-volunteer organization. Due to the high volume of applications, we ask that you be patient in waiting for a reply. Please do not submit duplicate applications or separate requests for response. Doing this will not accelerate the review process in any way."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
for
cats = [[UIAlertView alloc] initWithTitle:#"**Read this first!**"
message:#"Thank you for considering to adopt a cat from our shelter. PLEASE READ THIS FORM CAREFULLY.\n\nThis on-line form is intended to assist you in selecting a cat that is suitable for you, your family, and your lifestyle.\n\nThe Friends of the Plymouth Pound have established guidelines and policies that must be met in order for your pre-screening application to be approved.\n\nThe information you provide is essential to facilitate the application review process.\n\nIn order to be considered for adoption by the Friends of the Plymouth Pound, you must:\n\n\n*Be at least 18 years old.\n\n*Provide all the applicable information requested below.\n\n**Note, any data field marked with an asterisk character (*) must be filled in. Incomplete application forms will not be considered for review and will be denied automatically.**\n\n*Understand that this is a pre-screening form.\n\n\nThe Friends of the Plymouth Pound will contact you and approve you if, and only if, all requirements have been met.\n\nUpon review of your pre-screening application, you will be contacted by the Friends of the Plymouth Pound to notify you if your application has been accepted and if further information is needed. \n\n\n**Please note that we do contact all personal references and veterinarians, and we must speak with them personally. In addition, in some cases, a pre-adoption home visit may also be required.**\n\nIn the event that your pre-screening application has been not been approved, we will notify you of same.\n\n\nTHE BOARD OF DIRECTORS OF THE FRIENDS OF THE PLYMOUTH POUND RESERVES THE RIGHT TO DENY ANY PRE-APPLICATION BASED ON THE ORGANIZATION'S ESTABLISHED STANDARDS AND POLICIES, INCLUDING, BUT NOT LIMITED TO, INCOMPLETE INFORMATION, NON-DISCLOSURE OR OMISSION OF PERTINENT FACTS, AND NON-COMPLIANCE WITH ACCEPTED STANDARDS.\n\n\nUpon approval of your application and transfer of the animal, you will be charged a $150.00 adoption fee per cat.\n\n\nWe are an all-volunteer organization. Due to the high volume of applications, we ask that you be patient in waiting for a reply. Please do not submit duplicate applications or separate requests for response. Doing this will not accelerate the review process in any way."
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
In the View Did Load

iOS: How to authenticate a user after login (for auto login)?

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;
}

Facebook Connect on iPhone question

When you use facebook connect on the iPhone do you have to use the supplied login button and login screen built into the framework? The reason I ask is because I'm also using twitter and I would like to have the same user experience when they log in to user as they have when they log in to facebook. So I can either replicate the login screen facebook connect uses for twitter or just not use the facebook connect login screen all together.
Login button: no. Login screen: yes. I added FB Connect integration to my FriendFeed app for iPhone, Stir, and skipped the login button. Instead, a user can choose a "Share on Facebook" button on a UIActionSheet and the app either displays a login screen or automatically posts a link depending on whether the user is authenticated.
Here's a code snippet for you. If the session is successfully resumed, then a method on your FBSession object's delegate will be called.
if (![fbSession resume]) {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:fbSession] autorelease];
[dialog show];
}
- (void)session:(FBSession*)session didLogin:(FBUID)uid {
NSLog(#"Hooray, I'm logged in to Facebook!");
}
Apologies for being a little vague in my example above. To be honest, I find FBConnect to be a bit of a mystery and tried my best to implement it and get away from it as quickly as possible in my app. Let me know if you need more information and I'll put together a more-concrete answer.
Per the request below:
You can get an FBSession object with FBSession's +sessionForApplication:secret:delegate class method. You call -resume on the session object. If it returns YES, it'll immediately call your delegate's -session:didLogin: method, which is where you should put your FB-dependent actions. If it does not successfully -resume, then you need to create an FBLoginDialog, as seen in the code snippet above. Make sense? Let me know if you need more info

How to keep me logged in with facebook connect on iPhone?

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