来自本机Android应用程序的Rails用户身份验证

来自本机Android应用程序的Rails用户身份验证,android,ruby-on-rails,authentication,token,Android,Ruby On Rails,Authentication,Token,我正在尝试开发一个Rails应用程序,它将主要与Android应用程序用户进行通信。人们应该能够在应用程序中注册和登录(他们只能在登录时执行大多数请求) 关于如何在应用程序上实现“存储会话”的等效功能,我已经阅读了许多教程,但所有教程都建议使用gem'designe'及其:token\u authenticable,该工具已被弃用了一段时间 我需要关于如何执行类似任务的严肃建议。据我所知,客户端发送一个带有参数的请求,例如{email:some@email.com,密码:“pw12345”},我

我正在尝试开发一个Rails应用程序,它将主要与Android应用程序用户进行通信。人们应该能够在应用程序中注册和登录(他们只能在登录时执行大多数请求)

关于如何在应用程序上实现“存储会话”的等效功能,我已经阅读了许多教程,但所有教程都建议使用
gem'designe'
及其
:token\u authenticable
,该工具已被弃用了一段时间

我需要关于如何执行类似任务的严肃建议。据我所知,客户端发送一个带有参数的请求,例如
{email:some@email.com,密码:“pw12345”}
,我检查它们是否与现有用户匹配,并检索一个字符串令牌,从现在起,此客户端将通过头发送每个请求(例如
{“我的应用程序用户电子邮件”):some@email.com,“我的应用程序用户令牌”:“abcdef123456”}

我已经用假值设置了一些方法,例如

def login
  if valid_user?(params[:email], params[:password])
    render json: {user_token: default_user_token}
  else
    render json: {message: 'Couldn\'t login'}, status: 401
  end
end
其中,
default\u user\u token
是固定字符串,
valid\u user?
也与固定值进行比较

我想我的问题是知道这是否是正确的方法,如果是,我如何创建一个
用户
模型来创建和验证令牌?

额外的代码位

def verify_token # This already works by using default values in the Android app code
  email = request.headers['HTTP_MY_APP_USER_EMAIL']
  token = request.headers['HTTP_MY_APP_USER_TOKEN']
  user = User.find_by_email(email)
  user && user.valid_token?(token) # returns true for default_user_token, for now
end

我认为您的方法是正确的。您可以在模型中添加一个auth_令牌字段,并在用户登录时生成一个新的。您可以像这样生成令牌:

def generate_authentication_token!
    begin
        self.auth_token = Devise.friendly_token
    end while self.class.exists?(auth_token: auth_token)
end
module Authenticable

  #Devise overwritten method
  def current_user
    @current_user ||= User.find_by(auth_token: request.headers['Authorization'])
  end

  def authenticate_with_token!
    render json: { errors: "Not authenticated" }, status: :unauthorized unless user_signed_in?
  end

  def user_signed_in?
    current_user.present?
  end

end
然后,您可以创建一个身份验证服务,该服务要求每个请求都使用用户令牌,如下所示:

def generate_authentication_token!
    begin
        self.auth_token = Devise.friendly_token
    end while self.class.exists?(auth_token: auth_token)
end
module Authenticable

  #Devise overwritten method
  def current_user
    @current_user ||= User.find_by(auth_token: request.headers['Authorization'])
  end

  def authenticate_with_token!
    render json: { errors: "Not authenticated" }, status: :unauthorized unless user_signed_in?
  end

  def user_signed_in?
    current_user.present?
  end

end
然后,您可以创建SessionController,使用Desive登录/注销用户:

def create
    user_password = params[:session][:password]
    user_email = params[:session][:email]
    user = user_email.present? && User.find_by(email: user_email)

    if user
      if user.valid_password? user_password
        sign_in user, store: false
        user.generate_authentication_token!
        user.save
        render json: user, root: :user, status: 200, location: [:api, user]
      else
        render json: { errors: "Invalid email or password" }, status: 422
      end
    else
      render json: { errors: "Invalid email or password" }, status: 422
    end
  end

def destroy
    user = User.find_by(auth_token: params[:id])
    user.generate_authentication_token!
    user.save
    head 204
end

我在github上有一个使用此解决方案的repo:

您也可以尝试查看jwt。非常感谢,Bruno!这与我最终编写的代码非常接近。除了我没有使用Desive,所以我必须创建一个单独的令牌模型类和其他小的添加项。我还可以验证用户电子邮件(从请求头)在检查它是否是有效的令牌之前,为了避免一个我认为是导致他们不赞成的问题
:token\u authenticable
很高兴帮助我的朋友:)