songtianlun
63cebef027
- Implement remember me checkbox in login form - Update sessions controller to handle remember me logic - Enhance session management to prevent session hijacking - Add tests for remember me functionality This commit introduces a "Remember me" feature that allows users to stay logged in across sessions. It includes updates to the login form, session handling in the controller, and additional tests to ensure the functionality works as expected. The changes also improve security by validating session tokens to prevent session hijacking.
56 lines
1.6 KiB
Ruby
56 lines
1.6 KiB
Ruby
class User < ApplicationRecord
|
|
attr_accessor :remember_token
|
|
# before_save { self.email = email.downcase }
|
|
before_save { email.downcase! }
|
|
validates :name, presence: true, length: { maximum: 50 }
|
|
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
|
|
validates :email, presence: true, length: { maximum: 255 },
|
|
format: { with: VALID_EMAIL_REGEX },
|
|
uniqueness: true
|
|
has_secure_password
|
|
validates :password, presence: true, length: { minimum: 6 }
|
|
|
|
def User.digest(string)
|
|
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
|
|
BCrypt::Engine.cost
|
|
BCrypt::Password.create(string, cost: cost)
|
|
end
|
|
|
|
def User.new_token
|
|
SecureRandom.urlsafe_base64
|
|
end
|
|
|
|
def remember
|
|
self.remember_token = User.new_token
|
|
update_attribute(:remember_digest, User.digest(remember_token))
|
|
remember_digest
|
|
end
|
|
|
|
# 返回一个会话令牌,防止会话劫持
|
|
# 简单起见,直接使用记忆令牌
|
|
def session_token
|
|
remember_digest || remember
|
|
end
|
|
|
|
class << self
|
|
def digest(string)
|
|
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
|
|
BCrypt::Engine.cost
|
|
BCrypt::Password.create(string, cost: cost)
|
|
end
|
|
|
|
def new_token
|
|
SecureRandom.urlsafe_base64
|
|
end
|
|
end
|
|
|
|
def authenticated?(remember_token)
|
|
return false if remember_digest.nil?
|
|
BCrypt::Password.new(remember_digest).is_password?(remember_token)
|
|
end
|
|
|
|
def forget
|
|
update_attribute(:remember_digest, nil)
|
|
end
|
|
end
|