在 Rails 5 中使用 Devise 和 JWT 对用户进行身份验证时我缺少什么?
What am I missing for authenticating a user with Devise and JWT in Rails 5?
我按照本教程设置了 JWT 身份验证并设计了 https://www.sitepoint.com/introduction-to-using-jwt-in-rails/。我的 authentication_controller 看起来像这样:
class AuthenticationController < ApplicationController
def authenticate_user
user = User.find_for_database_authentication(email: params[:email])
if user.valid_password?(params[:password])
render json: payload(user)
else
render json: {errors: ['Invalid Username/Password']}, status:
:unauthorized
end
end
private
def payload(user)
return nil unless user && user.id
{
auth_token: JsonWebToken.encode({user_id: user.id}),
user: {id: user.id, email: user.email}
}
end
end
它映射到名为 auth_user 的路由,如我的 routes.rb 文件中所示:
Rails.application.routes.draw do
resources :reviews
resources :people do
resources :reviews
end
post 'auth_user' => 'authentication#authenticate_user'
devise_for :users, :controllers => {sessions: 'sessions', registrations:
'registrations'}
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
我的所有其他路线都有效,包括发布到设计路线,但这条路线给出了 500 内部服务器错误。非常感谢任何可能导致此行为的想法!就其价值而言,我正在使用 Rails 5.1.5、JWT 2.1.0 和 Devise 4.4.3。谢谢!
我在尝试发送请求后检查了 heroku 日志。它们看起来像这样:
2018-04-26T20:53:32.801349+00:00 app[web.1]: I, [2018-04-26T20:53:32.801222 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Started POST "/auth_user" for 199.116.73.196 at 2018-04-26 20:53:32 +0000
2018-04-26T20:53:32.824053+00:00 app[web.1]: I, [2018-04-26T20:53:32.823923 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Processing by AuthenticationController#authenticate_user as */*
2018-04-26T20:53:32.824188+00:00 app[web.1]: I, [2018-04-26T20:53:32.824119 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Parameters: {"email"=>"\"mike@mike.com\"", "password"=>"[FILTERED]"}
2018-04-26T20:53:32.953483+00:00 app[web.1]: D, [2018-04-26T20:53:32.953329 #4] DEBUG -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] [1m[36mUser Load (8.4ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."email" = ORDER BY "users"."id" ASC LIMIT [0m [["email", "\"mike@mike.com\""], ["LIMIT", 1]]
2018-04-26T20:53:32.963709+00:00 app[web.1]: I, [2018-04-26T20:53:32.963569 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Completed 500 Internal Server Error in 139ms (ActiveRecord: 53.2ms)
2018-04-26T20:53:32.964567+00:00 app[web.1]: F, [2018-04-26T20:53:32.964492 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224]
2018-04-26T20:53:32.964715+00:00 app[web.1]: F, [2018-04-26T20:53:32.964649 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] NoMethodError (undefined method `valid_password?' for nil:NilClass):
2018-04-26T20:53:32.964805+00:00 app[web.1]: F, [2018-04-26T20:53:32.964742 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224]
2018-04-26T20:53:32.964904+00:00 app[web.1]: F, [2018-04-26T20:53:32.964844 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] app/controllers/authentication_controller.rb:4:in `authenticate_user'
2018-04-26T20:53:32.966716+00:00 heroku[router]: at=info method=POST path="/auth_user" host=rateyouracquaintanceapi.herokuapp.com request_id=bb58b729-4d79-4940-b73d-2bc433c8d224 fwd="199.116.73.196" dyno=web.1 connect=1ms service=172ms status=500 bytes=203 protocol=https
仍然对发生了什么问题感到困惑,但至少现在很清楚问题出在哪里了!
将 authenticate_user 中的代码更改为:
def authenticate_user
user = User.find_for_database_authentication(email: params[:email])
if user && user.valid_password?(params[:password])
render json: payload(user)
else
render json: {errors: ['Invalid Username/Password']}, status:
:unauthorized
end
end
现在,如果未找到用户,我会得到预期的 json 响应,但如果我输入有效用户的数据,它不会给出正确的响应。这可能是 find_for_database_authentication 方法的问题吗?日志现在显示:
2018-04-26T21:24:07.327940+00:00 heroku[router]: at=info method=POST
path="/auth_user" host=rateyouracquaintanceapi.herokuapp.com
request_id=95dcfdd7-55d5-4a24-b8e4-d597737c4b02 fwd="199.116.73.196"
dyno=web.1 connect=1ms service=15ms status=401 bytes=286 protocol=https
2018-04-26T21:24:07.319101+00:00 app[web.1]: I, [2018-04-26T21:24:07.318981
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Started POST
"/auth_user" for 199.116.73.196 at 2018-04-26 21:24:07 +0000
2018-04-26T21:24:07.320412+00:00 app[web.1]: I, [2018-04-26T21:24:07.320296
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Processing by
AuthenticationController#authenticate_user as */*
2018-04-26T21:24:07.320476+00:00 app[web.1]: I, [2018-04-26T21:24:07.320410
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Parameters:
{"email"=>"\"mike@mike.com\"", "password"=>"[FILTERED]"}
2018-04-26T21:24:07.329226+00:00 app[web.1]: D, [2018-04-26T21:24:07.328689
#4] DEBUG -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] [1m[36mUser Load
(5.1ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."email"
=
LIMIT [0m [["email", "\"mike@mike.com\""], ["LIMIT", 1]]
2018-04-26T21:24:07.330108+00:00 app[web.1]: I, [2018-04-26T21:24:07.330005
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02]
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash
(0.17ms)
2018-04-26T21:24:07.330482+00:00 app[web.1]: I, [2018-04-26T21:24:07.330370
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Completed 401
Unauthorized in 10ms (Views: 1.0ms | ActiveRecord: 5.1ms)
查看您的日志,我发现:
NoMethodError (undefined method `valid_password?' for nil:NilClass):
这可能来自以下行:
user.valid_password?(params[:password])
这意味着您的 user
变量是 nil
。发生这种情况是因为 user = User.find_for_database_authentication(email: params[:email])
正在返回 nil
。
通过 运行 rails 控制台使用 heroku run rails c
检查您的用户是否存在于数据库中。如果没有,请创建它,您的代码应该可以正常工作。
我按照本教程设置了 JWT 身份验证并设计了 https://www.sitepoint.com/introduction-to-using-jwt-in-rails/。我的 authentication_controller 看起来像这样:
class AuthenticationController < ApplicationController
def authenticate_user
user = User.find_for_database_authentication(email: params[:email])
if user.valid_password?(params[:password])
render json: payload(user)
else
render json: {errors: ['Invalid Username/Password']}, status:
:unauthorized
end
end
private
def payload(user)
return nil unless user && user.id
{
auth_token: JsonWebToken.encode({user_id: user.id}),
user: {id: user.id, email: user.email}
}
end
end
它映射到名为 auth_user 的路由,如我的 routes.rb 文件中所示:
Rails.application.routes.draw do
resources :reviews
resources :people do
resources :reviews
end
post 'auth_user' => 'authentication#authenticate_user'
devise_for :users, :controllers => {sessions: 'sessions', registrations:
'registrations'}
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
end
我的所有其他路线都有效,包括发布到设计路线,但这条路线给出了 500 内部服务器错误。非常感谢任何可能导致此行为的想法!就其价值而言,我正在使用 Rails 5.1.5、JWT 2.1.0 和 Devise 4.4.3。谢谢!
我在尝试发送请求后检查了 heroku 日志。它们看起来像这样:
2018-04-26T20:53:32.801349+00:00 app[web.1]: I, [2018-04-26T20:53:32.801222 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Started POST "/auth_user" for 199.116.73.196 at 2018-04-26 20:53:32 +0000
2018-04-26T20:53:32.824053+00:00 app[web.1]: I, [2018-04-26T20:53:32.823923 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Processing by AuthenticationController#authenticate_user as */*
2018-04-26T20:53:32.824188+00:00 app[web.1]: I, [2018-04-26T20:53:32.824119 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Parameters: {"email"=>"\"mike@mike.com\"", "password"=>"[FILTERED]"}
2018-04-26T20:53:32.953483+00:00 app[web.1]: D, [2018-04-26T20:53:32.953329 #4] DEBUG -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] [1m[36mUser Load (8.4ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."email" = ORDER BY "users"."id" ASC LIMIT [0m [["email", "\"mike@mike.com\""], ["LIMIT", 1]]
2018-04-26T20:53:32.963709+00:00 app[web.1]: I, [2018-04-26T20:53:32.963569 #4] INFO -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] Completed 500 Internal Server Error in 139ms (ActiveRecord: 53.2ms)
2018-04-26T20:53:32.964567+00:00 app[web.1]: F, [2018-04-26T20:53:32.964492 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224]
2018-04-26T20:53:32.964715+00:00 app[web.1]: F, [2018-04-26T20:53:32.964649 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] NoMethodError (undefined method `valid_password?' for nil:NilClass):
2018-04-26T20:53:32.964805+00:00 app[web.1]: F, [2018-04-26T20:53:32.964742 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224]
2018-04-26T20:53:32.964904+00:00 app[web.1]: F, [2018-04-26T20:53:32.964844 #4] FATAL -- : [bb58b729-4d79-4940-b73d-2bc433c8d224] app/controllers/authentication_controller.rb:4:in `authenticate_user'
2018-04-26T20:53:32.966716+00:00 heroku[router]: at=info method=POST path="/auth_user" host=rateyouracquaintanceapi.herokuapp.com request_id=bb58b729-4d79-4940-b73d-2bc433c8d224 fwd="199.116.73.196" dyno=web.1 connect=1ms service=172ms status=500 bytes=203 protocol=https
仍然对发生了什么问题感到困惑,但至少现在很清楚问题出在哪里了!
将 authenticate_user 中的代码更改为:
def authenticate_user
user = User.find_for_database_authentication(email: params[:email])
if user && user.valid_password?(params[:password])
render json: payload(user)
else
render json: {errors: ['Invalid Username/Password']}, status:
:unauthorized
end
end
现在,如果未找到用户,我会得到预期的 json 响应,但如果我输入有效用户的数据,它不会给出正确的响应。这可能是 find_for_database_authentication 方法的问题吗?日志现在显示:
2018-04-26T21:24:07.327940+00:00 heroku[router]: at=info method=POST
path="/auth_user" host=rateyouracquaintanceapi.herokuapp.com
request_id=95dcfdd7-55d5-4a24-b8e4-d597737c4b02 fwd="199.116.73.196"
dyno=web.1 connect=1ms service=15ms status=401 bytes=286 protocol=https
2018-04-26T21:24:07.319101+00:00 app[web.1]: I, [2018-04-26T21:24:07.318981
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Started POST
"/auth_user" for 199.116.73.196 at 2018-04-26 21:24:07 +0000
2018-04-26T21:24:07.320412+00:00 app[web.1]: I, [2018-04-26T21:24:07.320296
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Processing by
AuthenticationController#authenticate_user as */*
2018-04-26T21:24:07.320476+00:00 app[web.1]: I, [2018-04-26T21:24:07.320410
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Parameters:
{"email"=>"\"mike@mike.com\"", "password"=>"[FILTERED]"}
2018-04-26T21:24:07.329226+00:00 app[web.1]: D, [2018-04-26T21:24:07.328689
#4] DEBUG -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] [1m[36mUser Load
(5.1ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."email"
=
LIMIT [0m [["email", "\"mike@mike.com\""], ["LIMIT", 1]]
2018-04-26T21:24:07.330108+00:00 app[web.1]: I, [2018-04-26T21:24:07.330005
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02]
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash
(0.17ms)
2018-04-26T21:24:07.330482+00:00 app[web.1]: I, [2018-04-26T21:24:07.330370
#4] INFO -- : [95dcfdd7-55d5-4a24-b8e4-d597737c4b02] Completed 401
Unauthorized in 10ms (Views: 1.0ms | ActiveRecord: 5.1ms)
查看您的日志,我发现:
NoMethodError (undefined method `valid_password?' for nil:NilClass):
这可能来自以下行:
user.valid_password?(params[:password])
这意味着您的 user
变量是 nil
。发生这种情况是因为 user = User.find_for_database_authentication(email: params[:email])
正在返回 nil
。
通过 运行 rails 控制台使用 heroku run rails c
检查您的用户是否存在于数据库中。如果没有,请创建它,您的代码应该可以正常工作。