【问题标题】:Rails user authentication from native Android app来自原生 Android 应用程序的 Rails 用户身份验证
【发布时间】:2015-12-26 03:59:56
【问题描述】:

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

我浏览了许多关于如何在应用程序上执行相当于“存储会话”的教程,但所有教程都建议使用 gem 'devise' 及其 :token_authenticable,它们已被弃用 有一段时间了。

我想要关于如何执行等效操作的严肃建议。据我了解,客户端发送带有参数的请求,例如{email: "some@email.com", password: "pw12345"},我检查它们是否与现有用户匹配并检索字符串令牌,该客户端将从现在开始通过标头发送每个请求(例如{"my_app_user_email": "some@email.com", "my_app_user_token":"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_user_token 是固定字符串,valid_user? 也与固定值进行比较。

我想我的问题是知道这是否是正确的方法,如果是,我怎样才能创建一个 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

【问题讨论】:

标签: android ruby-on-rails authentication token


【解决方案1】:

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

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

然后,您可以创建一个使用 devise 登录/注销用户的 SessionsController:

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:https://github.com/brunojppb/api_on_rails

【讨论】:

  • 非常感谢,布鲁诺!这与我最终编码的内容很接近。除了我不使用 Devise,所以我不得不创建一个单独的 Token 模型类和其他一些小的添加。此外,我在检查它是否是有效令牌之前验证用户电子邮件(来自请求标头),以避免出现问题,我认为是导致他们弃用 :token_authenticable
  • 很高兴帮助我的朋友:)
猜你喜欢
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 2013-06-01
  • 2021-04-24
相关资源
最近更新 更多