无法使用自定义密码要求验证 CSRF 令牌的真实性
Can't verify CSRF token authenticity with Custom Password Requirements
我有一个 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
理想情况下,登录应该 return 带有身份验证令牌的 200 消息,就像创建帐户一样。
尝试使用 :with
键
将验证添加为散列
validates :password, format: {with: PASSWORD_CONFIRMATION}
https://guides.rubyonrails.org/active_record_validations.html#format
我必须调整两件事。首先,我需要在我的注册模型中传递 validations false
标志,所以 has_secure_password
变成了 has_secure_password :validations => false
.
其次,我在模型中的 password
上调用了错误的字段名称。通过在 password_digest
而不是 password
上调用 PASSWORD_CONFIRMATION
变量,我的登录开始工作了。
我有一个 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
理想情况下,登录应该 return 带有身份验证令牌的 200 消息,就像创建帐户一样。
尝试使用 :with
键
validates :password, format: {with: PASSWORD_CONFIRMATION}
https://guides.rubyonrails.org/active_record_validations.html#format
我必须调整两件事。首先,我需要在我的注册模型中传递 validations false
标志,所以 has_secure_password
变成了 has_secure_password :validations => false
.
其次,我在模型中的 password
上调用了错误的字段名称。通过在 password_digest
而不是 password
上调用 PASSWORD_CONFIRMATION
变量,我的登录开始工作了。