使用Devise Gem时登录认证失败,无法正常登录问题排查
问题现象
登录页面显示正常,但使用seeds.rb中已存在的用户信息登录时,始终触发else分支返回登录页,无法跳转首页。曾尝试将user.authenticate(params[:password])修改为page.authenticate(params[:password]),问题未解决。
相关代码
def sign_in page = User.find_by(email: params[:email]) if page.present? && page.authenticate(params[:password]) session[:user_id] = page.id redirect_to root_path, notice: "You have successfully logged in" else flash[:alert] = "Invalid info" redirect_to login_path end end
请求日志
Started POST "/login" for ::1 at 2022-11-15 19:30:14 -0600
Processing by PagesController#sign_in as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "session"=>{"email"=>"hi@email.com", "password"=>"[FILTERED]"}, "commit"=>"Login"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."email" IS NULL LIMIT $1 [["LIMIT", 1]]
↳ app/controllers/pages_controller.rb:14:in `sign_in'
Redirected to http://localhost:3000/login
Completed 302 Found in 188ms (ActiveRecord: 2.1ms | Allocations: 8011)
Started GET "/login" for ::1 at 2022-11-15 19:30:14 -0600
Processing by PagesController#login as TURBO_STREAM
Rendering layout layouts/application.html.erb
Rendering pages/login.html.erb within layouts/application
Rendered pages/login.html.erb within layouts/application (Duration: 1.2ms | Allocations: 817)
Rendered shared/_flash.html.erb (Duration: 0.1ms | Allocations: 31)
Rendered layout layouts/application.html.erb (Duration: 80.3ms | Allocations: 6806)
Completed 200 OK in 102ms (Views: 82.3ms | ActiveRecord: 0.0ms | Allocations: 7152)
问题分析与修复方案
从日志的SQL查询语句能直接定位问题:查询条件是WHERE "users"."email" IS NULL,说明params[:email]取值为nil。结合请求参数结构,邮箱和密码是嵌套在session参数里的,所以正确的取值方式应该是params[:session][:email]和params[:session][:password],而非直接读取params[:email]。
修复后的代码:
def sign_in page = User.find_by(email: params[:session][:email]) if page.present? && page.authenticate(params[:session][:password]) session[:user_id] = page.id redirect_to root_path, notice: "登录成功" else flash[:alert] = "账号或密码错误" redirect_to login_path end end
内容的提问来源于stack exchange,提问作者Sync Vinyu

