Created
February 21, 2014 18:59
-
-
Save frnsys/9140873 to your computer and use it in GitHub Desktop.
Flask-Security login via iOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface LoginViewController : UIViewController <UITextFieldDelegate, UIWebViewDelegate> | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "LoginViewController.h" | |
@interface LoginViewController () { | |
UITextField *_emailField; | |
UITextField *_passwordField; | |
} | |
@end | |
@implementation LoginViewController | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
CGRect screenRect = [[UIScreen mainScreen] bounds]; | |
CGFloat screenWidth = screenRect.size.width; | |
CGFloat screenHeight = screenRect.size.height; | |
CGFloat buttonWidth = 200; | |
CGFloat buttonHeight = 50; | |
CGFloat buttonMargin = 25; | |
// Create login button | |
UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; | |
loginButton.frame = CGRectMake(screenWidth/2 - buttonWidth/2, screenHeight - buttonHeight*2, buttonWidth, buttonHeight); | |
[loginButton setTitle:@"Login" forState:UIControlStateNormal]; | |
[loginButton addTarget:self action:@selector(login:) forControlEvents:UIControlEventTouchUpInside]; | |
[self.view addSubview:loginButton]; | |
// Create text fields | |
CGFloat fieldWidth = 200; | |
CGFloat fieldHeight = 50; | |
_emailField = [[UITextField alloc] initWithFrame:CGRectMake(screenWidth/2 - fieldWidth/2, fieldHeight*2, fieldWidth, fieldHeight)]; | |
[_emailField setAutocapitalizationType:UITextAutocapitalizationTypeNone]; | |
_emailField.delegate = self; | |
_emailField.placeholder = @"email"; | |
_emailField.borderStyle = UITextBorderStyleLine; | |
_emailField.layer.borderColor = [[UIColor grayColor] CGColor]; | |
_emailField.layer.borderWidth = 1.0; | |
[self.view addSubview:_emailField]; | |
_passwordField = [[UITextField alloc] initWithFrame:CGRectMake(screenWidth/2 - fieldWidth/2, _emailField.frame.origin.y + (fieldHeight * 2), fieldWidth, fieldHeight)]; | |
[_passwordField setAutocapitalizationType:UITextAutocapitalizationTypeNone]; | |
_passwordField.delegate = self; | |
_passwordField.secureTextEntry = YES; | |
_passwordField.placeholder = @"password"; | |
_passwordField.borderStyle = UITextBorderStyleLine; | |
_passwordField.layer.borderColor = [[UIColor grayColor] CGColor]; | |
_passwordField.layer.borderWidth = 1.0; | |
[self.view addSubview:_passwordField]; | |
} | |
- (void)login:(id)sender | |
{ | |
if (_emailField.text.length == 0) { | |
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Email" message:@"What's your email?" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; | |
[alert show]; | |
} else if (_passwordField.text.length == 0){ | |
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Password" message:@"Did you forget your password?" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; | |
[alert show]; | |
} else { | |
/* | |
Workaround to authenticate the user through the app. | |
See: https://github.com/mattupstate/flask-security/issues/30 | |
*/ | |
UIWebView* webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,0,0)]; | |
webView.delegate = self; | |
[self.view addSubview:webView]; // the web view must be added as a subview in order for it to "load". | |
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"/login" relativeToURL:[NSURL URLWithString:kArgosAPIBaseURLString]]]]; | |
} | |
} | |
# pragma mark - UIWebViewDelegate | |
- (void)webViewDidFinishLoad:(UIWebView *)webView | |
{ | |
NSString *js = [NSString stringWithFormat:@" \ | |
var xmlHttp = new XMLHttpRequest(), \ | |
url = document.location.href, \ | |
csrf_token = document.getElementById('csrf_token').value, \ | |
params = 'email=%@&password=%@&csrf_token='+csrf_token; \ | |
xmlHttp.open('POST', url, false); \ | |
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); \ | |
xmlHttp.setRequestHeader('Content-Length', params.length); \ | |
xmlHttp.setRequestHeader('Connection', 'close'); \ | |
xmlHttp.send(params); \ | |
xmlHttp.responseText", _emailField.text, _passwordField.text]; // Note, can't use "return" or even have a ";" at the end, but this returns this value. | |
/* | |
Successful response looks like: | |
{ | |
"meta": { | |
"code": 200 | |
}, | |
"response": { | |
"user": { | |
"id": "the_user_id", | |
"authentication_token": "the_user_authentication_token" | |
} | |
} | |
} | |
*/ | |
NSString *response = [webView stringByEvaluatingJavaScriptFromString:js]; | |
NSLog(@"response: %@", response); | |
if ([response rangeOfString:@"Specified user does not exist"].location == NSNotFound && [response rangeOfString:@"Invalid password"].location == NSNotFound) { | |
NSData *jsonData = [response dataUsingEncoding:NSUTF8StringEncoding]; | |
NSError *error; | |
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; | |
NSLog(@"%@", jsonDict); | |
} else { | |
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Invalid credentials" message:@"You couldn't be logged in with the info you provided." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; | |
[alert show]; | |
} | |
} | |
# pragma mark - UITextFieldDelegate | |
- (BOOL)textFieldShouldReturn:(UITextField *)textField | |
{ | |
[textField resignFirstResponder]; | |
return NO; | |
} | |
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event | |
{ | |
[_emailField resignFirstResponder]; | |
[_passwordField resignFirstResponder]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment