我有一个Rails 5 API,并且正在设置身份验证。我添加了一些自定义密码要求,并且所有操作都可以用于创建帐户和注销帐户,但是每当我尝试登录用户时,都会出现Completed 422 Unprocessable Entity
错误和一条Can't verify CSRF token authenticity
消息。当我删除设置自定义密码验证的行时,一切正常。
我已将protect_from_forgery with: :null_session
添加到我的会话控制器中,但没有任何影响。
注册模型:
class Registration < ApplicationRecord
@username_length = (3..20)
PASSWORD_CONFIRMATION = /\A
(?=.{8,}) # Must contain 8 or more characters
(?=.*\d) # Must contain a digit
(?=.*[a-z]) # Must contain a lower case character
(?=.*[A-Z]) # Must contain an upper case character
(?=.*[[:^alnum:]]) # Must contain a symbol
/x
validates :username, uniqueness: true, length: @username_length
has_secure_password
validates :password, format: PASSWORD_CONFIRMATION
has_secure_token :auth_token
#used to logout
def invalidate_token
self.update_columns(auth_token: nil)
end
# makes sure use of built-in auth method bcrypt gives and hashes the password
# against the password_digest in the db
def self.validate_login(username, password)
registration = find_by(username: username)
if registration && registration.authenticate(password)
registration
end
end
end
会话控制器
class SessionsController < ApiController
skip_before_action :require_login, only: [:create], raise: false
protect_from_forgery with: :null_session
def create
if registration = Registration.validate_login(params[:username], params[:password])
allow_token_to_be_used_only_once_for(registration)
send_token_for_valid_login_of(registration)
else
render_unauthorized('Error with your login or password')
end
end
def destroy
logout
head :ok
end
private
def send_token_for_valid_login_of(registration)
render json: { token: registration.auth_token }
end
def allow_token_to_be_used_only_once_for(registration)
registration.regenerate_auth_token
end
def logout
current_registration.invalidate_token
end
end
注册控制器
class RegistrationController < ApplicationController
skip_before_action :verify_authenticity_token
def index; end
def custom
user = Registration.create!(registration_params)
puts "NEW USER #{user}"
render json: { token: user.auth_token, id: user.id }
end
def profile
user = Registration.find_by_auth_token!(request.headers[:token])
render json: {
user: { username: user.username, email: user.email, name: user.name }
}
end
private
def registration_params
params.require(:registration).permit(:username, :email, :password, :name)
end
end
理想情况下,登录应该返回200条消息,其中包含用于创建帐户的身份验证令牌。
答案 0 :(得分:0)
尝试使用:with
键将验证作为哈希添加
validates :password, format: {with: PASSWORD_CONFIRMATION}
https://guides.rubyonrails.org/active_record_validations.html#format
答案 1 :(得分:0)
我必须调整两件事。首先,我需要在注册模型中传递validations false
标志,因此has_secure_password
成为has_secure_password :validations => false
。
第二,我在模型的password
上调用了错误的字段名称。通过在PASSWORD_CONFIRMATION
而不是password_digest
上调用password
变量,我的登录开始起作用。