登录后设计未经授权的401

时间:2014-07-02 17:47:55

标签: ruby-on-rails devise

我正在使用rails 4.1.2并设计3.2.4

我之前看过这个问题,并在网上搜索解决方案,但所有的建议都没有用。成功登录后(对于成员,sign_in_count递增,current_member方法返回正确的成员),将路径设计回成员试图查看的原始页面,但

Completed 401 Unauthorized in 2ms

始终是结果,会员被重定向回登录页面(会话#new)

我的布局中有CSRF元标记。

我已尝试确定我想要可验证的路线:

devise_for :members, :path => '/' # i want sign in path to be /sign_in

devise_scope: :members do
  root 'application#index'
  get 'car_wash/:dealer_id', to: 'car_wash#show'
  post 'car_wash/:id/update', to: 'car_wash#update'
end

在控制器中我想要进行身份验证:

before_filter :authenticate_member!

在会员模型中

devise :database_authenticatable, :authenticatable, :rememberable, :trackable, :authentication_keys => [ :username ]

日志如下所示:

12:26:34 web.1         | Started POST "/sign_in" for 127.0.0.1 at 2014-07-02 12:26:34 -0500
12:26:34 web.1         | Processing by Members::SessionsController#create as HTML
12:26:34 web.1         |   Parameters: {"utf8"=>"✓","authenticity_token"=>"4tQIel82ktomEwfsvkgXzB7XfXJlmJxmlea9BnjaIYk=", "member"=>{"username"=>"John", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"}
12:26:34 web.1         |   Member Load (0.5ms)  SELECT  "members".* FROM "members"  WHERE "members"."username" = 'John' LIMIT 1
12:26:35 web.1         |    (0.3ms)  BEGIN
12:26:35 web.1         |    (0.3ms)  COMMIT
12:26:35 web.1         |    (0.2ms)  BEGIN
12:26:35 web.1         |   SQL (0.5ms)  UPDATE "members" SET "current_sign_in_at" = $1, "last_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "members"."id" = 1  [["current_sign_in_at", "2014-07-02 17:26:35.878880"], ["last_sign_in_at", "2014-07-02 17:23:42.608524"], ["sign_in_count", 23], ["updated_at", "2014-07-02 17:26:35.879614"]]
12:26:35 web.1         |    (6.3ms)  COMMIT
12:26:35 web.1         | Redirected to http://localhost:3000/
12:26:35 web.1         | Completed 302 Found in 1408ms (ActiveRecord: 8.6ms)
12:26:35 web.1         |
12:26:35 web.1         |
12:26:35 web.1         | Started GET "/" for 127.0.0.1 at 2014-07-02 12:26:35 -0500
12:26:35 web.1         | Processing by ApplicationController#index as HTML
12:26:35 web.1         | Completed 401 Unauthorized in 2ms
12:26:35 web.1         |
12:26:35 web.1         |
12:26:35 web.1         | Started GET "/sign_in" for 127.0.0.1 at 2014-07-02 12:26:35 -0500
12:26:35 web.1         | Processing by Members::SessionsController#new as HTML
12:26:35 web.1         |   Rendered devise/shared/_links.erb (0.1ms)
12:26:35 web.1         |   Rendered devise/sessions/new.html.erb within layouts/application (4.2ms)
12:26:35 web.1         |   Rendered shared/_header.html.haml (1.5ms)
12:26:35 web.1         | Completed 200 OK in 24ms (Views: 21.2ms | ActiveRecord: 1.0ms)

我正在使用自定义warden策略来根据对外部api的调用来确定身份验证的成功或失败。我已经逐步完成了逻辑的每一部分,并且工作得很好!

# config/initializers/devise.rb
config.warden do |manager|
  manager.intercept_401 = false
  manager.default_strategies(:scope => :member).unshift :member_login
end

但由于其他原因,成功登录并不坚持。

编辑:找到解决方案。问题在于我的自定义Warden auth策略(大惊喜):

Warden::Strategies.add(:member_login) do
  def member_params
    ActionController::Parameters.new(@response).permit(:first_name, :last_name, :role, :username, :external_api_user_id)
  end

  def valid?
    params[:member] && ( params[:member][:username] || params[:member][:password] )
  end

  def authenticate!
    member = Member.find_by_username(params[:member][:username])
    if authenticate_with_ppd_api
      if member
        member.update(member_params)
        success!(member)
      else
        member = Member.create(member_params)
        success!(member)
      end
    else
      fail!("Incorrect username or password")
    end
  end

  def authenticate_with_api
    @response = HTTParty.post('https://path.to.server/admin/login', body: { username: params[:member][:username], password: params[:member][:password] } )
    @response = JSON.parse(@response.body).first
    @response["authenticated"]
  end

end

我不允许会员使用'authenticity_token'。添加后,登录工作:

ActionController::Parameters.new(@response).permit(:authenticity_token, :first_name, :last_name, :role, :username, :external_api_user_id)

这对我来说仍然很困惑。我只是出于自己的目的更新/创建用户,而不是与身份验证有关。我不知道为什么更新真实性令牌不会自动发生。如果我知道默认的Warden策略正在做什么,这可能会有所帮助。那好吧。至少它正在发挥作用。

编辑:哦亲爱的!好吧,登录工作,但退出不行!这种“修复”确实可以登录但不能登出。向/ sign_out发送DELETE请求绝对没有任何意义。回到原点1

0 个答案:

没有答案