我正在使用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