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.

Сообщите мне, если вам нужно уточнение.