ruby on rails - tokens - Rails API: ¿la mejor manera de implementar la autenticación?
rails api token (4)
Estoy escribiendo una aplicación Rails 4 que expondrá una API para una aplicación móvil que aún no se ha desarrollado. Los usuarios se autenticarán utilizando un correo electrónico y una contraseña de la aplicación móvil.
Si bien he encontrado bastante información sobre el tema. Es difícil discernir qué es anticuado o no es óptimo. He leído sobre la autenticación básica HTTP, que no parece demasiado segura, y la autenticación basada en token HTTP, pero no estoy seguro de cómo acoplar eso con la autenticación regular de correo electrónico y contraseña (estoy usando Devise por la manera).
Solo me gustaría saber cuál es la mejor práctica actual sobre cómo implementar esto, así que me aseguraré de ir por el camino correcto.
@ Roma149 es más una preferencia personal, pero la mayoría de las personas que recién comienzan a usar Devise, ya que es la OMI más fácil. OAuth2 también es una buena opción. Como nota más importante, siempre puede ir a The Ruby Toolbox
Hay mucha buena información sobre gemas allí e incluso te dicen la edad y la popularidad de la gema. Esto también le permitirá diferenciar entre las gemas que la comunidad realmente está descubriendo ahora o las que se han vuelto obsoletas.
Recuerde que en Ruby y Ruby On Rails no siempre es lo que es mejor gema sabio sino lo que mejor se adapta a su proyecto.
El punto importante, desde una perspectiva de seguridad, es intercambiar el correo electrónico y la contraseña del usuario por un token una vez, y luego usar ese token para solicitudes posteriores. Esto es porque:
- No desea que la aplicación cliente sea responsable de mantener la contraseña del usuario, donde un error o ataque podría causar que se filtre; y
- Un token emitido por el servidor le brinda a usted (y a sus usuarios) la capacidad de expirar un token si es necesario, por ejemplo, bloquear un dispositivo robado o bloquear un cliente API que se porta mal.
Hay muchas maneras de lograr esto con diferentes niveles de complejidad.
Aquí hay un tutorial que es muy reciente y tiene un tutorial completo para crear una API en Rails con autenticación basada en token (sin usar Devise, pero aún relevante para comprender los conceptos): https://labs.kollegorna.se/blog/2015/04/build-an-api-now/
Otra opción es incluir el módulo a continuación en su MODELO de diseño y agregar el auth_token a su tabla.
aplicación / modelos / preocupaciones / token_authenticable.rb
module TokenAuthenticatable
extend ActiveSupport::Concern
included do
before_save :ensure_auth_token
end
module ClassMethods
def find_by_token(token)
find_by(auth_token: token)
end
end
def ensure_auth_token
self.auth_token = generate_auth_token if auth_token.blank?
end
private
def generate_auth_token
loop do
token = Devise.friendly_token
break token unless self.class.exists?(auth_token: token)
end
end
end
app / controllers / api / v1 / login_controller.rb
...
def login_user(params)
if params[:authentication]
@user = User.find_by(auth_token: params[:authentication])
if @user.nil?
render json: err(''login user by token failed'', ERR_USER_NOT_FOUND), status: :not_found
event(''login_user_by_auth_failed'', ''token'', params[:authentication])
return
else
render status: :ok, json: @user
return
end
else
user = user.find_by(email: params[:email])
if user.nil?
event(''login_user_failed_not_found'', ''user_email'', params[:email])
render json: err("login user not found #{params[:email]}", ERR_USER_NOT_FOUND), status: :not_found
return
end
if user.access_locked?
event(''login_user_blocked'', ''user_id'', user.id)
render json: err("login user account is locked : #{user.id}", ERR_USER_LOCKED), status: :unauthorized
return
end
unless user.try(:valid_password?, params[:password])
event("login_user_password_does_not_match #{user.id}", ''user_id'', user.id)
render json: err(''login user password does not match'', ERR_PASSWORD_NOT_MATCH), status: :unauthorized
return
end
event(''login_user_succeeded'', ''user_id'', user.id)
@user= user
if @user.save
response.headers[''authentication''] = @user.auth_token
render status: :ok, json: @user
return
else
render json: @user.errors, status: :unprocessable_entity
return
end
end
end
...
Editar: Corregido error tipográfico
Tiddle gem proporciona una estrategia de diseño para la autenticación de tokens en aplicaciones Ruby on Rails solo para API. Su característica principal es la compatibilidad con múltiples tokens por usuario .