set_user_by_token 设计问题
Devise issue with set_user_by_token
我遇到了一个可能很简单的问题,虽然我确实找到了它的位置,但我似乎找不到解决它的方法。
我想做的是使用 devise_token_auth 设置设计密码重置。我用令牌生成器设置了电子邮件,电子邮件链接到验证令牌的端点 '/api/auth/passwords/edit'
,然后重定向到我的前端密码重置表单(如果重要,在 reactjs 中完成),问题出现了当我实际提交表单时,我发送了令牌,我还发送了密码和确认、到期、uid 和所有其他 headers.
所以问题出在这里,设计密码控制器调用之前的操作set_user_by_token,我通过一些调试发现这就是问题所在,我创建了并使用 set_users_by_token 的默认代码覆盖模块,通过使用 binding.pry 我看到没有值通过方法调用传入,但是方法被调用是因为它成功了。
这里是方法代码
def set_user_by_token(mapping=nil)
# determine target authentication class
rc = resource_class(mapping)
# no default user defined
return unless rc
# gets the headers names, which was set in the initialize file
uid_name = DeviseTokenAuth.headers_names[:'uid']
access_token_name = DeviseTokenAuth.headers_names[:'access-token']
client_name = DeviseTokenAuth.headers_names[:'client']
# parse header for values necessary for authentication
uid = request.headers[uid_name] || params[uid_name]
@token ||= request.headers[access_token_name] || params[access_token_name]
@client_id ||= request.headers[client_name] || params[client_name]
# client_id isn't required, set to 'default' if absent
@client_id ||= 'default'
# check for an existing user, authenticated via warden/devise, if enabled
if DeviseTokenAuth.enable_standard_devise_support
binding.pry
devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
if devise_warden_user && devise_warden_user.tokens[@client_id].nil?
@used_auth_by_token = false
@resource = devise_warden_user
# REVIEW: The following line _should_ be safe to remove;
# the generated token does not get used anywhere.
# @resource.create_new_auth_token
end
end
# user has already been found and authenticated
return @resource if @resource && @resource.is_a?(rc)
# ensure we clear the client_id
if !@token
@client_id = nil
return
end
return false unless @token
# mitigate timing attacks by finding by uid instead of auth token
user = uid && rc.find_by(uid: uid)
if user && user.valid_token?(@token, @client_id)
# sign_in with bypass: true will be deprecated in the next version of Devise
if self.respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
bypass_sign_in(user, scope: :user)
else
sign_in(:user, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
end
return @resource = user
else
# zero all values previously set values
@client_id = nil
return @resource = nil
end
end
在最后它命中 else 并返回资源为 nil,因为没有满足其他条件。
非常感谢任何帮助,我很确定这就是问题所在,因为我已经调试了好几天,这就是它引导我的地方
如果你来这里是因为你遇到了同样的问题,希望我能提供帮助!经过几个小时的艰苦调试和测试,我克服了困难,这可能是一种变通方法或糟糕的方法,但它仍然可以使用设计方法。
在你的 passwords_controller.rb 中应该有一个 "before_action :set_user_by_token, only: => [:update]"
将“:set_user_by_token”更改为您想要命名的新方法,然后将方法复制并粘贴到原始 post 中并进行一些小的更改.
更改这些行:
uid = request.headers[uid_name] || params[uid_name]
@token ||= request.headers[access_token_name] || params[access_token_name]
@client_id ||= request.headers[client_name] || params[client_name]
到
uid = params[uid_name]
@token ||= params[access_token_name]
@client_id ||= params[client_name]
完成。现在您不必搞乱任何初始化器或顾虑器!
希望我能帮到别人!
我遇到了一个可能很简单的问题,虽然我确实找到了它的位置,但我似乎找不到解决它的方法。
我想做的是使用 devise_token_auth 设置设计密码重置。我用令牌生成器设置了电子邮件,电子邮件链接到验证令牌的端点 '/api/auth/passwords/edit'
,然后重定向到我的前端密码重置表单(如果重要,在 reactjs 中完成),问题出现了当我实际提交表单时,我发送了令牌,我还发送了密码和确认、到期、uid 和所有其他 headers.
所以问题出在这里,设计密码控制器调用之前的操作set_user_by_token,我通过一些调试发现这就是问题所在,我创建了并使用 set_users_by_token 的默认代码覆盖模块,通过使用 binding.pry 我看到没有值通过方法调用传入,但是方法被调用是因为它成功了。
这里是方法代码
def set_user_by_token(mapping=nil)
# determine target authentication class
rc = resource_class(mapping)
# no default user defined
return unless rc
# gets the headers names, which was set in the initialize file
uid_name = DeviseTokenAuth.headers_names[:'uid']
access_token_name = DeviseTokenAuth.headers_names[:'access-token']
client_name = DeviseTokenAuth.headers_names[:'client']
# parse header for values necessary for authentication
uid = request.headers[uid_name] || params[uid_name]
@token ||= request.headers[access_token_name] || params[access_token_name]
@client_id ||= request.headers[client_name] || params[client_name]
# client_id isn't required, set to 'default' if absent
@client_id ||= 'default'
# check for an existing user, authenticated via warden/devise, if enabled
if DeviseTokenAuth.enable_standard_devise_support
binding.pry
devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
if devise_warden_user && devise_warden_user.tokens[@client_id].nil?
@used_auth_by_token = false
@resource = devise_warden_user
# REVIEW: The following line _should_ be safe to remove;
# the generated token does not get used anywhere.
# @resource.create_new_auth_token
end
end
# user has already been found and authenticated
return @resource if @resource && @resource.is_a?(rc)
# ensure we clear the client_id
if !@token
@client_id = nil
return
end
return false unless @token
# mitigate timing attacks by finding by uid instead of auth token
user = uid && rc.find_by(uid: uid)
if user && user.valid_token?(@token, @client_id)
# sign_in with bypass: true will be deprecated in the next version of Devise
if self.respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
bypass_sign_in(user, scope: :user)
else
sign_in(:user, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
end
return @resource = user
else
# zero all values previously set values
@client_id = nil
return @resource = nil
end
end
在最后它命中 else 并返回资源为 nil,因为没有满足其他条件。
非常感谢任何帮助,我很确定这就是问题所在,因为我已经调试了好几天,这就是它引导我的地方
如果你来这里是因为你遇到了同样的问题,希望我能提供帮助!经过几个小时的艰苦调试和测试,我克服了困难,这可能是一种变通方法或糟糕的方法,但它仍然可以使用设计方法。
在你的 passwords_controller.rb 中应该有一个 "before_action :set_user_by_token, only: => [:update]"
将“:set_user_by_token”更改为您想要命名的新方法,然后将方法复制并粘贴到原始 post 中并进行一些小的更改.
更改这些行:
uid = request.headers[uid_name] || params[uid_name]
@token ||= request.headers[access_token_name] || params[access_token_name]
@client_id ||= request.headers[client_name] || params[client_name]
到
uid = params[uid_name]
@token ||= params[access_token_name]
@client_id ||= params[client_name]
完成。现在您不必搞乱任何初始化器或顾虑器!
希望我能帮到别人!