【问题标题】:Rails authentication error using bcrypt使用 bcrypt 的 Rails 身份验证错误
【发布时间】:2016-11-24 12:57:33
【问题描述】:

我有一个希望在 rails app API 上显示的用户列表。我正在使用 bcrypt 对密码进行哈希处理。我已经创建并检查了我在 rails 控制台上有几个用户的列表:

2.2.2 :010 > User.all
  User Load (8.9ms)  SELECT "users".* FROM "users"
 => #<ActiveRecord::Relation [#<User id: 2, created_at: "2016-07-19 06:23:35", updated_at: "2016-07-19 06:23:35", username: "iggy1", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, password_digest: "$2a$10$We2V5sFx3XJNHP9iHTx.5udLA9hEbJVDOcA01nemj0R...">,

我正在本地主机上测试这个。我的目标是转到http://localhost:3000/api/users 并获得一份 json 格式的所有用户列表。

当我访问该站点时,系统提示我用户名和密码。我输入了用户的用户名和密码之一:“iggy1”、“helloworld”。我看到这个错误信息:

SQLite3::SQLException: no such column: users.password: SELECT "users".* FROM "users" WHERE "users"."username" = ? AND "users"."password" = 'helloworld'

我的架构如下:

create_table "users", force: :cascade do |t|
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "username"
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.string   "password_digest"
  end

我试着玩了一下。我按照bcrypt website 上给出的代码进行操作。

这是我的代码:

#controller/api/users_controller.rb

class UsersController < ApplicationController
  def create
    @user = User.new(params[:user])
    @user.password = params[:password]
    @user.save!
  end
end


#controllers/users_controller.rb

class UsersController < ApplicationController
  def create
    @user = User.new(params[:user])
    @user.password = params[:password]
    @user.save!
  end
end


#models/user.rb

require 'bcrypt'

class User < ActiveRecord::Base
  #include 'bcrypt'
  has_many :lists
  has_many :items, through: :lists
  has_secure_password

  def password
    @password ||= Password.new(password_hash)
  end

  def password=(new_password)
    @password = Password.create(new_password)
    self.password_hash = @password
  end

end


#controllers/application_controller.rb

class ApiController < ApplicationController
  skip_before_action :verify_authenticity_token
  private

def authenticated?
    authenticate_or_request_with_http_basic {|username, password| User.where( username: username, password: password).present? }
  end
end

#config routes

Rails.application.routes.draw do
  namespace :api, defaults: { format: :json} do #supports JSON requests
    resources :users
  end
end

现在,当我取消注释 include 'bcrypt' 行时,当我转到 http://localhost:3000/api/users 时会看到另一个错误

wrong argument type String (expected Module)

我对为什么会发生这种情况有几个假设。

首先,我认为是因为我使用了 bcrypt,它有 password_digest。我的架构上没有专门的password(在应用程序控制器上,它明确表示用户名和密码)。我认为 Rails 可能试图寻找“密码”但找不到。不过,我对 bcrypt 的了解还不足以说是这种情况。

其次,在bcrypt website 上,我没有实现以下代码,因为我不知道该放在哪里。这可能是 bcrypt 没有按照我的意愿行事的情况吗?

  def login
    @user = User.find_by_email(params[:email])
    if @user.password == params[:password]
      give_token
    else
      redirect_to home_url
    end
  end

我不确定缺少什么。

【问题讨论】:

    标签: ruby-on-rails ruby api bcrypt


    【解决方案1】:

    您的数据库架构中有两个可用于密码的字段

    如果您使用 Devise 进行身份验证,则 encrypted_password 字段用于存储密码。

    【讨论】:

    • 这是否意味着我使用encrypted_password,而不是password,在这种情况下是'helloworld'?
    • 是的,如果你用过Device Gem,那么它会自动转换你的密码
    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 2013-02-23
    • 2018-04-27
    • 1970-01-01
    • 2018-03-02
    • 2015-08-08
    • 2021-03-17
    相关资源
    最近更新 更多