ruby-on-rails-5 - 在 Rails 5.2 上使用两种不同用户模型的 Bcrypt
问题描述
我有两个迁移表:父母和老师。我使用 Bcrypt 进行注册。我不知道应该如何处理登录和会话控制器(会话助手)。我可以注册新用户,当用户注册时,他只能在导航栏中看到注销链接。但是,我无法注销用户,我不确定如何定义会话控制器和会话助手中的方法。也许有人可以帮我解决这个问题?我找不到关于不同用户模型的 bcrypt 的信息——这个东西不流行还是很容易,我只是愚蠢而且什么都不懂?
class SessionsController < ApplicationController
include SessionsHelper
def new
end
def create
teacher = Teacher.find_by(email: params[:session][:email])
parent = Parent.find_by(email: params[:session][:email])
if teacher && teacher.authenticate(params[:session][:password])
log_in teacher
redirect_to documents_path
flash[:notice] = "Welcome!"
elsif parent && parent.authenticate(params[:session][:password])
log_in parent
redirect_to root_path
flash[:notice] = "Welcome!"
else
flash[:alert] = "Please log in again!"
render 'new'
end
end
def destroy
if log_out parent
redirect_to root_path
elsif log_out teacher
redirect_to root_path
end
end
end
这是我的会话助手:
module SessionsHelper
# Logs in the given user.
def log_in(parent)
session[:parent_id] = parent.id
end
def log_in(teacher)
session[:teacher_id] = teacher.id
end
# Returns the current logged-in user (if any).
def current_teacher
@current_teacher ||= Teacher.find_by(id: session[:teacher_id])
end
def current_parent
@current_parent ||= Parent.find_by(id: session[:parent_id])
end
# Returns true if the user is logged in, false otherwise.
def logged_in?(teacher)
!current_teacher.nil?
end
def logged_in?(parent)
!current_parent.nil?
end
def log_out(teacher)
session.delete(:teacher_id)
@current_teacher = nil
end
def log_out(parent)
session.delete(:parent_id)
@current_parent = nil
end
end
解决方案
我不知道您申请的详细信息,但我可以解释一般情况。
首先,具有登录功能的控制器不必命名sessions_controller
,命名什么的都可以。
而 Bcrypt 基本上只是一个用于加密密码的库。主要过程是检查用户输入的密码是否有效,无需解密。如何实现控制器逻辑没有明确的答案。
显然,用户分为两种类型,教师和家长,并且可能各自具有不同的功能。所以本质上,我想将两个登录过程分成单独的控制器或动作。因为每个登录过程都不一样。
但是如果由于 UI 限制,用户必须从同一页面登录,教师和家长将使用相同的 URL 登录。如果您处于这种情况,则在同一控制器和操作中实施将是合适的。
毕竟,这取决于如何设计您的应用程序。所以你的代码并不总是错误的。
但是,查看您的代码,Teacher 或 Parent 仅通过电子邮件来判断,这是否是正确的方法值得怀疑。我还没有看到很多具有不同权限的用户从同一页面登录的网站。
我认为它基本上是根据老师或家长划分登录页面。如果分割登录页面,示例如下。
class TeachersController < ApplicationController
include SessionsHelper
def login
end
def login_action
teacher = Teacher.find_by(email: params[:teacher][:email])
if teacher && teacher.authenticate(params[:teacher][:password])
log_in teacher
flash[:notice] = 'Welcome!'
redirect_to root_path
else
flash[:notice] = 'Invalid log in information!'
redirect_to action: :login
end
end
def logout
teacher = Teacher.find(session[:teacher_id])
log_out teacher
redirect_to root_path
end
end
class ParentsController < ApplicationController
include SessionsHelper
def login
end
def login_action
parent = Parent.find_by(email: params[:parent][:email])
if parent && parent.authenticate(params[:parent][:password])
log_in parent
flash[:notice] = 'Welcome!'
redirect_to root_path
else
flash[:notice] = 'Invalid log in information!'
redirect_to action: :login
end
end
def logout
parent = Parent.find(session[:parent_id])
log_out parent
redirect_to root_path
end
end
虽然这不是主要问题,但是你在helpers
目录中写了 session_helper 吗?
通常,helper 用于实现视图逻辑,所以如果要在控制器中共享方法,请ActiveSupport::Concern
在concerns
目录中使用。
推荐阅读
- c - 在 C 中使用 switch 语句调用方法后,循环自动运行
- docker - 无法创建或配置 Hyper-V 虚拟机:序列不包含任何元素
- c# - Razor - 发布 Url 参数和表单数据
- plot - 添加 45 度参考线
- javascript - 如何在 React.JS 中将数据从一个组件传递到另一个组件
- mysql - MYSQL - 如何在表中更新后创建触发器,以增加 +1 另一个表中列的值?
- reactjs - 如何将参数作为参数发送回函数传递
- html - 绝对位置但不与其他对象重叠
- html - 如何在主页上显示用户帖子
- identityserver4 - Blazor WebAssembly 与 IdentityServer 4 自定义身份