Autenticación http en dispositivos y Rails 3

Tengo una aplicación que utiliza el dispositivo en los Rails 3. Me gustaría habilitar la autenticación http para poder autenticarme en mi aplicación web desde una aplicación de iPhone. ¿Cómo puedo autenticarme desde mi aplicación de iPhone para diseñar?

¿Es esto seguro o debo autenticar de manera diferente?

Desde el punto de vista del diseño tienes 3 opciones:

1) Use la autenticación http básica: su aplicación de iPhone tiene una clave secreta, que se incluye en el código de su aplicación de iPhone, que se utiliza para autenticar cada solicitud con la aplicación web. Búsqueda en Google: “Diseñar autenticación HTTP básica”

2) Puede usar https teniendo un certificado público en su aplicación de iPhone y un certificado privado en su aplicación web. Esta es una gran cantidad de trabajo para configurar correctamente, es muy seguro ya que su aplicación de iPhone y el servidor Rails están intercambiando mensajes a través de un canal encriptado. La seguridad también es transparente para su código de Rails, ya que la autenticación se realiza en el nivel de transporte.

3) La aplicación de iPhone se conecta a la aplicación web mediante https, obtiene un token de autenticación que luego utiliza para hacer llamadas a la aplicación web a través de http regular. Más seguro que 1, ya que la clave puede caducar, bastante trabajo para implementar y muy escalable. ( http://matteomelani.wordpress.com/2011/10/17/authentication-for-mobile-devices/ )

La mayoría de las aplicaciones usan la solución 1.

Espero que esto ayude.

EDITAR: para implementar la autenticación http (ya sea básica o de resumen), le sugiero que mire:

http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Basic.html y https://github.com/plataformatec/devise/wiki/How-To:-Use-HTTP-Basic-Authentication

Los pasos precisos dependerán de la stack del servidor Rails.

EDIT 2: no creo que Devise proporcione una manera de obtener el auth_token. Puedo ver que puedes probar varias soluciones:

  • cuando el usuario inicia sesión en el servidor, recupera el identificador de autenticación y lo coloca en la cookie. No es muy seguro a menos que lo cifres con una clave secreta compartida.

  • puede proporcionar un servicio web https que su aplicación de iPhone utiliza para obtener un token de usuario. Su aplicación de iPhone realizará la solicitud inmediatamente después de recibir la solicitud del usuario para iniciar sesión.

Lo siento, no puedo ser de más ayuda con algún código real.

Esto depende en gran medida de cómo esté implementando las cosas en el lado del servidor, pero implementamos esto utilizando la tercera opción de Matteo. Tengo una implementación de Rails 3.1 utilizando un dispositivo. La ruta al inicio de sesión es /users/login.json. Primero construya el cuerpo JSON para iniciar sesión con un código como este:

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]; 

que produce este JSON:

 {"user":{"password":"blahblahblah","email":"admin@*****.com"}} 

Te envío una solicitud de url POST con un código como este:

 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]; 

La respuesta que recibo contiene JSON. Configuramos el lado del servidor para devolver un 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 = "admin@******.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" = ""; name = "Joe Smith"; "remember_created_at" = "2012-03-29T20:35:43Z"; "reset_password_sent_at" = ""; "reset_password_token" = ""; "session_auth_token" = "3FRgX6CYlzQJGC8tRWwqEjFaMMFKarQAYKTy3u84M0U="; "sign_in_count" = 145; status = 1; "unlock_token" = ""; "updated_at" = "2012-04-04T04:29:15Z"; } 

Almacenamos session_auth_token y luego lo enviamos de vuelta con cada solicitud en un encabezado, algo como esto:

 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]; 

Ese parámetro [self sessionAuth] contiene el session_auth_token.

Déjame saber si necesitas una aclaración.