HTTP-аутентификация в устройствах и рельсах 3
У меня есть приложение, которое использует devise на rails 3. Я бы хотел включить HTTP-аутентификацию, чтобы я мог аутентифицироваться в своем веб-приложении из приложения iPhone. Как я могу аутентифицироваться из своего iPhone-приложения для разработки?
Является ли это безопасным или я должен аутентифицироваться по-другому?
Ответы
Ответ 1
С точки зрения дизайна у вас есть 3 варианта:
1) Используйте базовую http-аутентификацию: ваше приложение IPhone имеет секретный ключ, который испечен в вашем коде приложения IPhone, который использует для аутентификации каждого запроса с помощью веб-приложения.
Поиск в Google: "Определите базовую HTTP-аутентификацию"
2) Вы можете использовать https, имея общедоступные сертификаты в своем приложении IPhone и частные сертификаты в своем веб-приложении. Это очень сложная работа по настройке, это очень безопасно, так как ваше приложение IPhone и сервер Rails обмениваются сообщениями по зашифрованному каналу. Безопасность также прозрачна для вашего кода рельсов, поскольку проверка подлинности выполняется на уровне транспорта.
3) Приложение IPhone подключается к веб-приложению с помощью https, получает токен аутентификации, который затем используется для совершения вызовов в веб-приложение по регулярному http. Более безопасный, чем 1, так как ключ может истечь, довольно много работы для реализации и очень масштабируемого.
(http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/)
Большинство приложений используют решение 1.
Надеюсь на эту помощь.
EDIT: для реализации аутентификации HTTP (базового или дайджест) я предлагаю вам посмотреть:
http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html
а также
https://github.com/plataformatec/devise/wiki/How-To:-Use-HTTP-Basic-Authentication
Точные шаги будут зависеть от вашего стека серверов Rails.
ИЗМЕНИТЬ 2: Я не думаю, что Devise предоставляет способ получить auth_token. Я вижу, вы можете попробовать несколько решений:
-
когда пользователь регистрируется на сервере, получает идентификатор_имя_файла и помещает его в файл cookie. Не очень безопасно, если вы не зашифруете его с помощью общего секретного ключа.
-
вы можете предоставить веб-службу https, которую приложение IPhone использует для получения токена пользователя. Приложение IPhone сделает запрос сразу после получения запроса пользователя для входа.
Извините, я не могу больше помочь с каким-то реальным кодом.
Ответ 2
Это во многом зависит от того, как вы реализуете вещи на стороне сервера, но мы реализовали это с помощью Matteo 3rd option. У меня есть реализация рельсов 3.1 с использованием разработки. Маршрут к логину -/users/login.json. Сначала создайте тело JSON для входа с кодом следующим образом:
NSMutableDictionary *loginDictionary = [NSMutableDictionary dictionary];
NSMutableDictionary *usernamePasswordDictionary = [NSMutableDictionary dictionary];
[usernamePasswordDictionary setObject:username forKey:@"email"];
[usernamePasswordDictionary setObject:password forKey:@"password"];
[loginDictionary setObject:usernamePasswordDictionary forKey:@"user"];
NSData *data = [NSJSONSerialization dataWithJSONObject:loginDictionary options:0 error:&error];
который дает этот JSON:
{"user":{"password":"blahblahblah","email":"[email protected]*****.com"}}
Я отправляю запрос URL-адреса POST с кодом, подобным этому:
NSString *postUrlString = [NSString stringWithFormat:@"%@users/login.json", kServerAPIBaseURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:postUrlString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:kTimeoutInterval];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-type"];
[request setHTTPBody:data];
Ответ, который я получаю, содержит JSON. Мы настроили серверную сторону, чтобы вернуть session_auth_token:
{
admin = 1;
"created_at" = "2012-01-25T00:15:58Z";
"current_sign_in_at" = "2012-04-04T04:29:15Z";
"current_sign_in_ip" = "75.163.148.101";
email = "[email protected]******.com";
"encrypted_password" = "*****";
"failed_attempts" = 0;
id = 1;
"last_sign_in_at" = "2012-04-03T03:37:18Z";
"last_sign_in_ip" = "75.163.148.101";
"locked_at" = "<null>";
name = "Joe Smith";
"remember_created_at" = "2012-03-29T20:35:43Z";
"reset_password_sent_at" = "<null>";
"reset_password_token" = "<null>";
"session_auth_token" = "3FRgX6CYlzQJGC8tRWwqEjFaMMFKarQAYKTy3u84M0U=";
"sign_in_count" = 145;
status = 1;
"unlock_token" = "<null>";
"updated_at" = "2012-04-04T04:29:15Z";
}
Мы сохраняем этот session_auth_token, а затем отправляем его с каждым запросом в заголовке, примерно так:
NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self postUrlString]]...
[postRequest setHTTPMethod:@"POST"];
[postRequest setValue:@"application/json" forHTTPHeaderField:@"Content-type"];
[postRequest setValue:[self sessionAuth] forHTTPHeaderField:@"X-CSRF-Token"];
[postRequest setHTTPBody:data];
Этот параметр [self sessionAuth]
содержит session_auth_token.
Сообщите мне, если вам нужно уточнение.