[英]Failing to understand Devise after sign in redirect with Rails
我是一个Rails / devise新手,我已经做了几个月的搜索,但没有找到解决方案。
我想做的事情似乎很简单:使用Rails和Devise gem(v 3.2.3)成功登录后,将用户重定向到上一页,但是我所有的登录重定向都转到根路径。 这很烦人,因为如果我向某人发送指向他们必须在其中进行身份验证的特定页面的链接,它将再次将他们重定向到主页。
我知道其他有关SO的问题也会提出这个问题,但我想我是在问有关Devise中代码的更高层次的问题。
所以我的总体问题是:我对问题和解决方案的理解正确吗? 为了解决,我需要:
我在第177行的Devise lib / devise / controllers / helpers.rb中查看一些代码注释:
# The default url to be used after signing in. This is used by all Devise
# controllers and you can overwrite it in your ApplicationController to
# provide a custom hook for a custom resource.
#
# By default, it first tries to find a valid resource_return_to key in the
# session, then it fallbacks to resource_root_path, otherwise it uses the
# root path. For a user scope, you can define the default url in
# the following way:
然后在该文件的第204行:
def after_sign_in_path_for(resource_or_scope)
stored_location_for(resource_or_scope) || signed_in_root_path(resource_or_scope)
end
这使我在store_location.rb的stored_location_for方法:
def stored_location_for(resource_or_scope)
session_key = stored_location_key_for(resource_or_scope)
if is_navigational_format?
session.delete(session_key)
else
session[session_key]
end
end
因此,当新用户登录时,将在session#create中调用代码:
# POST /resource/sign_in
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_flashing_format?
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
然后调用我上面粘贴的after_sign_in_path_for(resource)
。 我的问题是:这是否是我能够将某人重定向到上一页而不是根路径所需的一切? 是否需要补充一些遗漏? 如何测试after_sign_in_path_for(resource)不为零? 其他人有经验吗?
仅供参考,这里是我的路线文件:
Rails.application.routes.draw do
get 'orders/index'
resources "orders", :controller => :my_orders, :as => :orders
get 'faq/index'
resources "faq", :controller => :faq, :as => :faq
get 'guidelines/index'
resources "guidelines", :controller => :guidelines, :as => :guidelines
get 'terms_of_use/index'
resources "terms-of-use", :controller => :terms_of_use, :as => :terms_of_use
get 'privacy_policy/index'
resources "privacy-policy", :controller => :privacy_policy, :as => :privacy_policy
# This line mounts Spree's routes at the root of your application.
# This means, any requests to URLs such as /products, will go to Spree::ProductsController.
# If you would like to change where this engine is mounted, simply change the :at option to something different.
#
# We ask that you don't use the :as option here, as Spree relies on it being the default of "spree"
mount Spree::Core::Engine, :at => '/store'
# Need to adjust this for FB authentication
devise_for :users, controllers: { registrations: 'users/registrations', passwords: 'users/passwords' }
devise_scope :user do
get 'register', to: 'devise/registrations#new', as: :register
get 'signin', to: 'devise/sessions#new', as: :signin
get 'logout', to: 'devise/sessions#destroy', as: :logout
get 'edit', to: 'devise/registrations#edit', as: :edit
put "update" => 'devise/registrations#update', as: :updateprofile
end
get 'welcome/index'
get '/sell' => 'sell#index'
get '/:id', to: 'profiles#show', as: :profile
root 'welcome#index'
# for setting up the stripe webhook
post '/hooks/stripe' => 'hooks#stripe'
end
如果有用的话,我会很高兴地透露更多的代码。
先感谢您,
编辑做了更多的挖掘以缩小范围。 我注释掉了store_location.rb中的许多代码,以查看会话密钥。 注释掉if / else语句,因为它是一种导航格式,显然(这意味着什么?):
def stored_location_for(resource_or_scope)
session_key = stored_location_key_for(resource_or_scope)
puts "session_key = #{session_key}"
puts "session = #{session}"
puts "session[session_key] = #{session[session_key]}"
# if is_navigational_format?
# puts "is navigational"
# session.delete(session_key)
# else
# puts "is not navigational"
puts "session[session_key] = #{session[session_key]}"
session[session_key]
# end
end
并且我在此方法中添加了一些与session_key绑定的put语句。
def stored_location_key_for(resource_or_scope)
scope = Devise::Mapping.find_scope!(resource_or_scope)
"#{scope}_return_to"
end
这是命令行中的输出:
Started POST "/users/sign_in" for 127.0.0.1 at 2015-05-03 22:34:31 -0500
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"/Xjy/neoPX2nGqpz+FtACjtTx4nnkhiRuVln44Zi4qI=", "user"=>{"email"=>"brandon.a.hay@gmail.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'brandon.a.hay@gmail.com' ORDER BY "users"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (0.3ms) UPDATE "users" SET "current_sign_in_at" = ?, "last_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = 7 [["current_sign_in_at", "2015-05-04 03:34:31.179646"], ["last_sign_in_at", "2015-05-04 03:32:08.608830"], ["sign_in_count", 65], ["updated_at", "2015-05-04 03:34:31.181312"]]
Spree::Role Load (0.1ms) SELECT "spree_roles".* FROM "spree_roles" WHERE "spree_roles"."name" = 'admin' LIMIT 1
SQL (0.1ms) INSERT INTO "spree_roles_users" ("role_id", "user_id") VALUES (?, ?) [["role_id", 1], ["user_id", 7]]
(1.5ms) commit transaction
session_key = user_return_to
session = #<ActionDispatch::Request::Session:0x007fc7c4af34b0>
session[session_key] =
stored location =
session_key = user_return_to
session = #<ActionDispatch::Request::Session:0x007fc7c4af34b0>
session[session_key] =
Redirected to http://localhost:3000/
因此,stored_location_key_for返回用户类并将其绑定到作用域。 session_key返回“ user_return_to”,session返回一个动作分配请求会话,session [session_key]为nil。 有人可以帮助我理解这一点吗?
这篇文章的答案解决了我的问题: 使用omniauth重定向回当前页面并设计
我必须在应用程序控制器中添加商店位置回调:
#application_controller.rb
before_filter :store_current_location, :unless => :devise_controller?
def store_current_location
store_location_for(:user, request.url)
end
您需要像这样重定向控制器中的路由
class HomeController < ApplicationController
def index
if user_signed_in?
redirect_to blogs_index_path
end
end
end
转到终端并输入耙路径,找到所需的路径,然后将其重定向到那里。 希望这可以帮助!
似乎尝试存储的位置永远不会存储在错误的位置。 看看这段代码https://github.com/plataformatec/devise/blob/v3.2.3/lib/devise/failure_app.rb
身份验证失败时,总是会调用失败应用程序。 您可以在第57行看到它存储了已访问的uri。 您可以尝试在此位置进行调试。
我可以想到几个为什么这不起作用的原因:
如果找不到导致问题的原因,则可以尝试将代码从设计失败应用程序复制到应用程序控制器。 使用prepend_before_filter将位置存储在任何其他before_filters之前。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.