XCode,身份验证和NSUserDefaults

时间:2012-01-06 14:03:17

标签: php mysql xcode authentication

我正在开发一个应用程序,它将使用Web视图与Web服务器(带有MySQL后端的PHP)连接。我有应用程序使用静态URL作为测试,但现在我需要调整实际的用户交互。

我一直在寻找HTTP身份验证的解决方案,但我认为这句话不正确,因为我得到的大部分搜索结果都与“REST”请求有关。我将使用URL(PHP / MySQL)来验证身份验证,并且根据我的经验不相信它符合REST。

我在这台服务器上还没有SSL,所以我不确定Cocoa有哪些选项。

我的问题:

  1. 如果帐户ID尚未存储在本地,是否可以创建加载的视图?

  2. 如果是这样,如果需要身份验证,我可以将应用程序编码为取代我创建的故事板吗?

  3. 如果第1步和第2步有效,我该如何与我的网络服务器进行身份验证? (首选方法是提交用户电子邮件和密码的MD5,因为它是当前存储在数据库中的密码)

  4. 理想情况下我很想只是提交URL像“的login.php login=me@blah.com&密码=(md5hash)”,并具有提供响应任一给我“AUTH =真安培;帐户ID = 5”或“auth = false”...然后使用iPhone应用程序向用户报告auth错误或将帐户ID保存到NSUserDefaults以备将来使用(以后绕过auth)并加载已经存在的正常故事板。

    任何建议都将受到赞赏。

    谢谢,

    Silver Tiger

2 个答案:

答案 0 :(得分:3)

你的想法非常接近。我对用户登录过程采用了非常类似的方法。

我目前正在将电子邮件和密码加密并散列为1 40个char令牌。如果登录返回成功,我将令牌保存到NSUserDefaults。我将此令牌用于所有其他Web请求,直到用户注销,此时我删除了用户默认值。

以下是我用于同一过程的几个片段:

// see if a login already exists
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.token = [defaults stringForKey:@"token"];

// if the token is nil/blank, launch login view
if(self.token == nil || [self.token isEqualToString:@""]) {
    [self loadStartView];
    return;
}

// build the request to update status
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];
NSString *stringData = [NSString stringWithFormat:@"<your api string here"];
NSString *requestData = stringData;
NSData *myRequestData = [NSData dataWithBytes: [requestData UTF8String] length: [requestData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:[NSString  stringWithFormat:@"<your url request here>"]]];
[request setHTTPMethod: @"POST"];
[request setHTTPBody: myRequestData];
NSData *jsonData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
NSString *json = [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease];
NSDictionary *payloadData = [json JSONValue];

[request release];

if([[payloadData objectForKey:@"success"] boolValue]) { // this is designed around my api, but you get the idea
    //NSLog(@"updateStatus: %@", payloadData);
    // updates the api version for every call
    [defaults setObject:self.token forKey:@"token"];
}

答案 1 :(得分:2)

我没有足够的空间在笔记中发表评论。这是最终的代码。不是我想要它完成工作:

为了让JSONValue工作,我必须下载并在我的项目中包含json frameowrk,如下所示:

https://github.com/stig/json-framework

一旦我有了这个,我从JSONValue函数得到一个不完整的错误。我对PHP页面请求的原始URL请求提供了如下JSON响应:

{ “成功”:“0”, “AccountID:”4“, “错误”:“” }

由于某些原因,JSONValue函数不喜欢此输出,我不得不将其更改为更基本的不太优选的版本,如下所示:

[ “0”, “4”, “”]

一旦我完成了这项工作,代码的最终副本如下:

在我的主视图中,在应用启动时加载我添加以下内容以确定是否存在现有帐户ID并启动“登录”视图(如果不存在):

- (void)viewDidLoad
{
    NSString *accountID = [[NSUserDefaults standardUserDefaults] stringForKey:@"AccountID"];
    if (![accountID length]) {
        UIViewController *login = [self.storyboard instantiateViewControllerWithIdentifier:@"Login"];
        [self presentModalViewController:login animated:YES];
    }
    [super viewDidLoad];
}

登录只不过是2个文本字段和一个用于身份验证的按钮。 这是我添加到按钮的功能,它目前有效:

-(IBAction)authenticate:(id)sender{
    // This will be the validation code
    // First we'll grab the field values
    NSString *currentEmail = emailField.text;
    NSString *currentPassword = passField.text;
    // Now we will grab the user default settings (saved preferences)
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    // build the request to update status
    NSString *myURL = [NSString stringWithFormat:@"http://www.myurl.com/auth.php?e=%@&p=%@",currentEmail,currentPassword];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:myURL]];
    [request setHTTPMethod:@"GET"];
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *responseString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
    NSArray *responseArray = [responseString JSONValue];
    NSString *success = [responseArray objectAtIndex:0];
    NSString *AccountID = [responseArray objectAtIndex:1];
    NSString *error = [responseArray objectAtIndex:2];
    if([success boolValue]) {
        NSLog(@"User is Authenticated");
        UIAlertView *auth1 = [[UIAlertView alloc] initWithTitle:@"T-of-U" message:@"Successfully Authenticated" delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil];
        [auth1 show];
        [defaults setObject:AccountID forKey:@"AccountID"];
        [self dismissModalViewControllerAnimated:YES];
    } else {
        NSString *authMessage = error;
        UIAlertView *auth2 = [[UIAlertView alloc] initWithTitle:@"Authentication Failed:" message:authMessage delegate:self cancelButtonTitle:@"ok" otherButtonTitles: nil];
        [auth2 show];
    }
}

我更喜欢一个键值对NSDictionary,但每次我发送带有键值对的json响应时,JSONValue都会失败,所以我最终只是将它作为一个简单的json响应和数组位置中的引用对象来获取我的变量

如果有一种方法可以将键值对放入字典中,那将是很好的,虽然我可能没有正确地形成我的json响应(PHP有json_encode($ data)方法,可以按预期创建json,但是Objective C函数不会解析它。)