我是不是必须在学生表中添加 password_digest 列才能使 student.authenticate(password) 运行?即使我使用的是设计?

Posted

技术标签:

【中文标题】我是不是必须在学生表中添加 password_digest 列才能使 student.authenticate(password) 运行?即使我使用的是设计?【英文标题】:Should I have to add password_digest column in my students table to make student.authenticate(password) run ? Even if I am using Devise?我是否必须在学生表中添加 password_digest 列才能使 student.authenticate(password) 运行?即使我使用的是设计? 【发布时间】:2020-03-05 10:38:03 【问题描述】:

我正在按照以下链接的步骤在我的代码中实现基于令牌的身份验证 API:

https://www.pluralsight.com/guides/token-based-authentication-with-ruby-on-rails-5-api

authentication_controller.rb 是:

class AuthenticationController < ApplicationController
 skip_before_action :authenticate_request
 skip_before_action :verify_authenticity_token

 def authenticate
  binding.pry
   command = AuthenticateStudent.call(params[:corporative_email], params[:password])

   if command.success?
     render json:  auth_token: command.result 
   else
     render json:  error: command.errors , status: :unauthorized
   end
 end
end

authenticate_student.rb 是:

class AuthenticateStudent
  prepend SimpleCommand

  def initialize(corporative_email, password)
    binding.pry
    @corporative_email = corporative_email
    @password = password
  end

  def call
    binding.pry
    JsonWebToken.encode(student_id: student.id) if student
  end

  private

  attr_accessor :corporative_email, :password

  def student
    binding.pry
    student = Student.find_by_corporative_email(corporative_email)
    return student if student && student.authenticate(password)

    errors.add :student_authentication, 'invalid credentials'
    nil
  end
end

一切都很顺利,直到最后一次撬开代码在student.authenticate(password) 处中断并且服务器返回“ArgumentError(参数数量错误(给定 0,预期为 1)): ”。在控制台“密码”按预期返回“123456”,这对我来说意味着给定的参数编号应该是 1 而不是零。

有人知道这里发生了什么吗?

【问题讨论】:

我在学生模型中添加了password_digest列,报错响应一样。 在设计中,数据库可验证的列称为encrypted_password。如果您打算使用 Devise,那不是一个很好的指南。由于 Devise 建立在 Warden 之上,因此您希望为基于令牌的身份验证创建一个warden 身份验证策略,而不是重新发明***并创建不会集成的东西。 729solutions.com/… 如果您只是创建一个仅 API 的应用程序,我会质疑您是否真的想使用 Devise。它非常臃肿,具有经典 Web 应用程序的功能。我会改用 Knock,这是一种更轻量级的 JWT 令牌身份验证解决方案。 选择一个,使用 ActiveModel::HasSecurePassword(这就是 has_secure_password password_digestauthenticate(password) 方法的来源)或使用 Devise 身份验证。如果我要使用 devise,那么我会寻找一个实际使用 devise 进行身份验证的教程。 事实上,我的最终目标是开发一个基于令牌的身份验证 API,它允许我的 webapp 的已验证/注册用户从 webapp 请求/下载内容到将要开发的移动应用程序。目前我的 webapp 使用 Devise 来验证用户访问。 【参考方案1】:

我找到了答案。如果您正在使用 devise 并想按照下面的教程进行操作,请忘记“gem 'bcrypt'”部分以及与之相关的所有内容(包括 has_secure_password 方法)。

https://www.pluralsight.com/guides/token-based-authentication-with-ruby-on-rails-5-api

最后在 commands/authenticate_student.rb (在我的例子中,我已经逐个学生更改了用户)替换该行:

return student if student && student.authenticate(password)

作者:

return student if student && student.valid_password?(password)

有效密码?是一种设计方法,将完成与身份验证相同的工作。

就是这样!

【讨论】:

以上是关于我是不是必须在学生表中添加 password_digest 列才能使 student.authenticate(password) 运行?即使我使用的是设计?的主要内容,如果未能解决你的问题,请参考以下文章

如何同时在 2 个表中添加字段?

如何在Sqlite的数据库表中添加其他列?

mssql 如何在已有的表中 添加多个列名?

检查表中是不是存在列,如果没有,则添加列

MySQL怎么往一个学生表中增加数据,我试了很多次总是不成功不知道为啥,1054(42S2)错误

使用 Data.plist 时向表中添加披露按钮