Remember me功能异常:勾选记忆逻辑不符问题排查求助
Let's break down the issues with your "Remember me" functionality and fix them step by step:
Core Problems Identified
Your
current_usermethod ignores theauth_tokencookie
Right now, yourcurrent_useronly checks forsession[:user_id]andcookies.signed[:user_id], but your SessionController sets acookies.permanent.signed[:auth_token]for persistent logins. This means your "remember me" cookie is never actually used to authenticate users, and the temporary session (which lasts until the browser closes) is keeping users logged in even when they don't check the box.Incorrect
remember_meparameter check
Rails'check_boxhelper submits values as strings, not integers. Soparams[:remember_me] == 1won't work as expected—you need to check for the string"1"instead.Confused temporary vs persistent login logic
You were callinglog_in(which sets a session) regardless of the remember me checkbox. This meant even unchecking the box kept users logged in via the browser session, making it look like the "remember me" feature was broken.
Fixes to Implement
1. Update current_user to handle persistent auth tokens
Modify the current_user method in your ApplicationController to validate and use the auth_token cookie:
def current_user # First check for temporary session login if (user_id = session[:user_id]) @current_user ||= User.find_by(id: user_id) # Then check for persistent remember-me token elsif (auth_token = cookies.signed[:auth_token]) user = User.find_by(auth_token: auth_token) if user # Automatically log the user in via session for better UX log_in user @current_user = user end end end
2. Add a forget method to clear persistent login data
Add this to your ApplicationController (you already had it as a helper method, now implement it):
def forget(user) user.update!(auth_token: nil) cookies.delete(:auth_token) end
3. Fix the SessionController create action
Clean up the logic to separate temporary and persistent login handling:
def create user = User.find_by_email(params[:email]) if user && user.authenticate(params[:password]) # Always set a temporary session for the current browser session log_in user if params[:remember_me] == '1' # Generate and save a persistent auth token token = SecureRandom.urlsafe_base64 user.update!(auth_token: token) # Set a permanent signed cookie (lasts ~20 years by default) cookies.permanent.signed[:auth_token] = token else # Clear any existing persistent login data forget(user) end redirect_to user else flash.now[:danger] = 'Invalid email/password combination' render 'new' end end
4. Improve the destroy (logout) action
Make sure logging out clears both the session and persistent cookie:
def destroy forget(current_user) if logged_in? reset_session @current_user = nil redirect_to root_path end
5. (Optional) Clarify the login form checkbox
Your existing form is fine, but you can explicitly set the default state for clarity:
<div class="field"> <%= form.label :"remember_me" %> <%= form.check_box :remember_me, checked: false %> </div>
Why This Works
- Checked "Remember me": Users get a temporary session and a persistent auth token cookie. Even after closing the browser, the
current_usermethod will find the token, validate it, and log them back in automatically. - Unchecked "Remember me": Only a temporary browser session is used. Closing the browser will invalidate the session, and any existing persistent token is cleared to prevent automatic login.
内容的提问来源于stack exchange,提问作者Minimalism

