使用API​​时如何使用Devise进行身份验证

时间:2018-08-01 04:16:55

标签: ruby-on-rails api devise

我知道还有其他与此类似的问题,但是在我的情况下,没有一个答案有效。我正在尝试通过API对用户进行身份验证。更具体地说,我有一个iPhone应用程序充当“客户端”,它将帖子请求发送到我拥有的会话控制器。在这里:

class V1::SessionsController < ApplicationController

  def create
    @user = User.find_by_username(params[:username])

    if @user
      if @user.valid_password?(params[:password])
        sign_in(@user)
        render :create
      else 
        render_error_for @user
      end
    else
      render json: {
        status: 'ERROR',
        data: ['Incorrect Username']
      }, status: :unauthorized
    end
  end 
end

我在线阅读了sign_in(@user)应该登录用户的信息,但这不能正常工作。此外,我读到您应该在重新登录用户之前像这样@user.reload进行登录。这也不起作用。我想知道这是否与我不是从Devise::SessionsController继承的事实有关。我学习了如何在线制作这样的会话控制器,所以可能是问题所在。

我测试的方法是通过在Rails控制台中运行user.last_sign_in_at,但是我得到的只是nil,我敢肯定,这意味着设计没有成功登录用户。感谢您的任何帮助,谢谢。

UPDATE

def create
    @user = User.find_by_username(params[:username])

    if @user
      if @user.valid_password?(params[:password])
        @user.last_sign_in_at = Time.now
        render :create
      else 
        render_error_for @user
      end
    else
      render json: {
        status: 'ERROR',
        data: ['Incorrect Username']
      }, status: :unauthorized
    end
  end

我找到了可能的解决方案,但是我没有将其标记为解决方案,因为在我看来,该解决方案并不安全。我实质上是用我自己的过程来创建会话,(并将DateTime分配给last_sign_in_at字段)代替了Devise的过程。这样安全吗?还是这样做不是一个好主意?硬编码Devise的sessions#create操作由于某些原因而无法工作。我推测这与以下事实有关:这是API,而不仅仅是常规网站。

2 个答案:

答案 0 :(得分:1)

如您所说的More specifically, I have an iPhone app acting as the "client" and it sends posts requests to a sessions controller I have

所以我可能认为您需要的响应将包括用户信息和身份验证令牌。

尝试这种方式:

class SessionsController < Devise::SessionsController

  skip_before_action :verify_authenticity_token # skip CSRF check for APIs
  respond_to :json

  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with(resource)
 end

 def respond_with(resource, opts = {})
   render json: resource.as_json(only: [:id,:email, :name, ... ])
                      .merge!({token: resource.token})
 end
end

关于令牌,您可以检查 :jwt_authenticatable, :jwt_revocation_strategy设计宝石。

因此,响应将具有用户和令牌:用户将是用户信息,令牌是此用户的身份验证令牌。 然后,您需要在下次调用另一个后端请求时存储该令牌,以确保下次将其包含在标头中作为授权。

在后端,我们根据身份验证令牌获得当前用户。

答案 1 :(得分:0)

您可以尝试device-token-auth gem,它是为API身份验证而设计的。

请选中documentation,其中描述了用法。