Skip to content

Instantly share code, notes, and snippets.

@frnsys
Created February 21, 2014 18:59
Show Gist options
  • Save frnsys/9140873 to your computer and use it in GitHub Desktop.
Save frnsys/9140873 to your computer and use it in GitHub Desktop.
Flask-Security login via iOS
@interface LoginViewController : UIViewController <UITextFieldDelegate, UIWebViewDelegate>
@end
#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