XCode, Authentication и NSUserDefaults - PullRequest
2 голосов
/ 06 января 2012

Я занимаюсь разработкой приложения, которое будет взаимодействовать с веб-сервером (PHP с серверной частью MySQL) с использованием веб-представлений. У меня есть приложение, работающее со статическими URL-адресами в качестве тестов, но теперь мне нужно настроить его для реального взаимодействия с пользователем.

Я искал решения для аутентификации HTTP, но считаю, что эта фраза неверна, поскольку большинство результатов поиска, которые я получаю, связаны с запросами "REST". Я буду использовать URL (PHP / MySQL) для проверки подлинности и не верю, что это квалифицируется как REST, исходя из моего опыта.

У меня еще нет SSL на этом сервере, поэтому я не уверен, какие опции доступны через Какао.

У меня есть вопросы:

  1. Есть ли способ создать представление, которое загружается, если идентификатор учетной записи еще не сохранен локально?

  2. Если это так, могу ли я написать приложение, чтобы заменить созданную мной раскадровку, если требуется аутентификация?

  3. Если шаги 1 и 2 работают, как я могу взаимодействовать с моим веб-сервером для аутентификации? (предпочтительным способом является отправка электронной почты пользователя и MD5 пароля, поскольку это то, что в настоящее время хранится в базе данных)

В идеале я хотел бы просто отправить URL-адрес, такой как «login.php?login=me@blah.com&password= (md5hash)», и получить предоставленный ответ либо дать мне «auth = true & accountID = 5», либо «auth = false». «... затем используйте приложение iPhone, чтобы либо сообщить пользователю об ошибке аутентификации, либо сохранить идентификатор учетной записи в NSUserDefaults для будущего использования (чтобы обойти аутентификацию позже) и загрузить обычную раскадровку, уже имеющуюся на месте.

Буду признателен за любые рекомендации.

Спасибо

Серебряный тигр

Ответы [ 2 ]

3 голосов
/ 06 января 2012

Вы довольно близки со своим мышлением. Я использую очень похожий подход к процессу входа моего пользователя.

В настоящее время я солю и хэширую электронную почту и пароль в 1 40 символьный токен. Если логин возвращается успешно, я сохраняю токен в NSUserDefaults. Я использую этот токен для всех остальных веб-запросов, выполняемых до тех пор, пока пользователь не выйдет из системы, после чего я удаляю настройки пользователя по умолчанию.

Вот несколько фрагментов, которые я использую для того же процесса:

// 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"];
}
2 голосов
/ 09 января 2012

Мне не хватило места для комментариев в заметках. Вот окончательный код. Хотя не то, что я хотел, он выполняет свою работу:

Чтобы заставить JSONValue работать, мне пришлось скачать и включить в свой проект json frameowrk, как показано здесь:

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

Как только я это установил, я получил неполную ошибку от функции JSONValue. мой исходный URL-запрос на мой PHP-запрос страницы предоставлял JSON-ответ следующим образом:

{ «успех»: «0», "AccountID:" 4 ", "ошибка": "" } * +1010 *

По какой-то причине функции JSONValue не понравился этот вывод, и мне пришлось изменить его на более базовую, менее предпочтительную версию, следующим образом:

[ "0", "4", ""]

После того, как у меня получилось, окончательная копия кода выглядит следующим образом:

В моем главном представлении, которое загружается при запуске приложения, я добавил следующее, чтобы определить, существует ли существующий идентификатор учетной записи, и запустить представление «Вход в систему», если оно отсутствует:

- (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 не будет ее анализировать).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...