Visión general
Estoy buscando crear una API (REST) para mi aplicación. El propósito inicial / primario será el consumo de aplicaciones móviles (iPhone, Android, Symbian, etc.). He estado buscando diferentes mecanismos de autenticación y autorización para API basadas en web (estudiando otras implementaciones). Tengo la cabeza concentrada en la mayoría de los conceptos fundamentales, pero todavía estoy buscando orientación en algunas áreas. Lo último que quiero hacer es reinventar la rueda, pero no encuentro ninguna solución estándar que se ajuste a mis criterios (sin embargo, mis criterios pueden estar equivocados, así que siéntete libre de criticar eso también). Además, quiero que la API sea la misma para todas las plataformas / aplicaciones que la consumen.
oAuth
Seguiré adelante y rechazaré mi objeción a oAuth, ya que sé que probablemente será la primera solución ofrecida. Para aplicaciones móviles (o más específicamente aplicaciones no web), parece incorrecto abandonar la aplicación (para ir a un navegador web) para la autenticación. Además, no hay forma (que yo sepa) de que el navegador devuelva la devolución de llamada a la aplicación (especialmente multiplataforma). Conozco un par de aplicaciones que hacen eso, pero se siente mal y da un descanso en la aplicación UX.
Requisitos
- El usuario ingresa el nombre de usuario / contraseña en la aplicación.
- Cada llamada a la API se identifica mediante la aplicación de llamada.
- Los gastos generales se mantienen al mínimo y el aspecto de autenticación es intuitivo para los desarrolladores.
- El mecanismo es seguro tanto para el usuario final (sus credenciales de inicio de sesión no están expuestas) como para el desarrollador (sus credenciales de aplicación no están expuestas).
- Si es posible, no requiera https (de ninguna manera es un requisito difícil).
Mis pensamientos actuales sobre la implementación
Un desarrollador externo solicitará una cuenta API. Recibirán un apikey y un apisecret. Cada solicitud requerirá como mínimo tres parámetros.
- apikey - dada al desarrollador en el registro
- marca de tiempo: funciona como un identificador único para cada mensaje para una apikey dada
- hash: un hash de la marca de tiempo + el apisecreto
Se requiere que la apikey identifique la aplicación que emite la solicitud. La marca de tiempo actúa de manera similar a oauth_nonce y evita / mitiga los ataques de repetición. El hash asegura que la solicitud fue emitida realmente por el propietario de la apikey dada.
Para las solicitudes autenticadas (las que se realizan en nombre de un usuario), todavía estoy indeciso entre ir con una ruta access_token o un combo de hash de nombre de usuario y contraseña. De cualquier manera, en algún momento se requerirá un combo de nombre de usuario / contraseña. Entonces, cuando lo haga, se usará un hash de varias piezas de información (apikey, apisecret, timestamp) + la contraseña. Me encantaría recibir comentarios sobre este aspecto. Para su información, primero tendrían que cambiar la contraseña, ya que no almaceno las contraseñas en mi sistema sin hash.
Conclusión
Para su información, esta no es una solicitud de cómo construir / estructurar la API en general, solo cómo manejar la autenticación y la autorización únicamente desde una aplicación.
Pensamientos aleatorios / preguntas extra
Para las API que solo requieren una apikey como parte de la solicitud, ¿cómo puede evitar que alguien que no sea el propietario de la apikey pueda ver la apikey (ya que se envió en claro) y realizar solicitudes excesivas para superar los límites de uso? Quizás acabo de pensar en esto, pero ¿no debería haber algo para autenticar que se verificó una solicitud al propietario de la apikey? En mi caso, ese era el propósito del apisecreto, nunca se muestra / transmite sin ser hash.
Hablando de hashes, ¿qué pasa con md5 vs hmac-sha1? ¿Realmente importa cuando todos los valores se combinan con datos suficientemente largos (es decir, apisecret)?
Anteriormente había estado considerando agregar una sal por usuario / fila al hash de contraseña de mis usuarios. Si tuviera que hacer eso, ¿cómo podría la aplicación ser capaz de crear un hash coincidente sin conocer la sal utilizada?