在我的应用程序中,如果有一个cookie集带有他们唯一的user_id_token(UUID),则认为用户已登录(有会话)。我在ApplicationController中有一个before_action,它需要一个当前用户,否则它会将用户注销。
class ApplicationController < ActionController::Base
before_action :require_user
def require_user
if current_user
true
else
flash[:error] = "No user found"
redirect_to logout_path
end
end
# Who is currently logged in?
def current_user
if cookies.signed[:user_id_token]
@current_user ||= User.find_by_id_token!(cookies.signed[:user_id_token])
end
end
helper_method :current_user
end
用户可以通过以下几种方式创建会话:
(1)通过电子邮件/密码组合登录
这是登录应用程序的"常见"方式。你输入你的电子邮件/密码,它们会通过一个表单张贴到一个操作中,该操作可以对你进行身份验证,并允许你通过设置cookie[:user_id_token]进入应用程序。
(2)密码重置
如果用户忘记了密码并重置了密码,则输入新的(有效)密码,然后通过设置cookie[:user_id_token]进行"身份验证"。然而,密码重置并不是POST到身份验证方法,因为他们已经通过使用发送到电子邮件的唯一password_reset_token"验证"了自己,该电子邮件提供了更改密码的唯一URL。
(3)确认新用户
与上面的(2)非常相似,用户会收到一封邀请电子邮件,其中包含一个唯一的confirmation_token URL,允许他们完成注册过程。一旦他们完成了确认(通过选择有效密码),他们就会被"验证",并通过设置cookie[:user_id_token]进入应用程序。
问题是有三种方法可以通过设置cookie进入应用程序。这是我有非常相似代码cookie[:user_id_token] = user.user_id_token
的三个地方。
我怎么能有一个单一的网关让用户进入我的应用程序?
我有一个SessionsController
,我正试图将其用作单一路径,但create_session
方法(cookie[:user_id_token]的设置)必须从登录表单中POST到,并在password_reset/confirmation页面上使用令牌id参数GETed。
如何通过对我的应用程序设置一个访问点来保持代码干燥并降低复杂性?
我想我找到了自己的解决方案;将单个"登录"操作放入applicationcontroller.rb文件中,并在适当的时候从相应的控制器调用它。这样,登录代码(cookie的设置等)都在一个位置,不会分布在几个不同的控制器中。