操作前回调方法多次重定向,同时强制用户在 rails 中更改密码
A Before action callback method redirects multiple times while forcing the user to change password in rails
一个场景需要,当用户登录时,如果没有更改密码,他应该redirect_to更改密码的路径我尝试了以下方式
1)
class ApplicationController < ActionController::Base
before_action :check_password, if: :current_user
def check_password
if current_user.present? &&
current_user.try(:created_at).try(:to_datetime) ==
current_user.try(:password_changed_at).try(:to_datetime)
redirect_to change_password_admin_user_path(current_user)
end
end
end
2)
class Admin::UsersController < ApplicationController
skip_before_action :check_password, only: [:change_password, :update_password]
def change_password
@user = User.find(params[:id])
end
def update_password
@user = User.find(params[:id])
if @user.valid_password?(params[:old_password])
if @user.update_attributes(password: params[:new_password], password_confirmation: params[:reenter_password])
flash[:notice] = 'Password changed successfully, please login with new password'
redirect_to new_user_session_path and return
else
flash[:alert] = @user.errors.full_messages.join(', ')
end
else
flash[:alert] = "Old password you've entered is invalid"
end
redirect_to change_password_admin_user_path(@user.id)
end
end
3)
class Admin::SessionsController < Devise::SessionsController
skip_before_action :check_password, only: :destroy
end
我强制用户更改密码,但它多次抛出重定向错误
1)
class ApplicationController < ActionController::Base
before_action :check_password, if: :current_user # this is why you're getting multiple redirect.
def check_password
if current_user.present? &&
current_user.try(:created_at).try(:to_datetime) ==
current_user.try(:password_changed_at).try(:to_datetime)
redirect_to change_password_admin_user_path(current_user)
end
end
end
所以,请不要这样使用。
如何将 check_password 方法移动到另一个控制器?
例如
class DashboardController < ActionController::Base
def dashboard
if current_user.present? &&
current_user.try(:created_at).try(:to_datetime) ==
current_user.try(:password_changed_at).try(:to_datetime)
redirect_to change_password_admin_user_path(current_user)
end
end
end
此外,除非他更改了密码,否则不要显示任何菜单。
根据您的评论,您正在使用 devise-security gem, so you can use the method need_change_password! (which will clear password_changed_at
) right after the user sign-up, so that the devise hook password_expirable 将检查并强制新用户更改通过,您无需自己处理此逻辑。
一个场景需要,当用户登录时,如果没有更改密码,他应该redirect_to更改密码的路径我尝试了以下方式
1)
class ApplicationController < ActionController::Base
before_action :check_password, if: :current_user
def check_password
if current_user.present? &&
current_user.try(:created_at).try(:to_datetime) ==
current_user.try(:password_changed_at).try(:to_datetime)
redirect_to change_password_admin_user_path(current_user)
end
end
end
2)
class Admin::UsersController < ApplicationController
skip_before_action :check_password, only: [:change_password, :update_password]
def change_password
@user = User.find(params[:id])
end
def update_password
@user = User.find(params[:id])
if @user.valid_password?(params[:old_password])
if @user.update_attributes(password: params[:new_password], password_confirmation: params[:reenter_password])
flash[:notice] = 'Password changed successfully, please login with new password'
redirect_to new_user_session_path and return
else
flash[:alert] = @user.errors.full_messages.join(', ')
end
else
flash[:alert] = "Old password you've entered is invalid"
end
redirect_to change_password_admin_user_path(@user.id)
end
end
3)
class Admin::SessionsController < Devise::SessionsController
skip_before_action :check_password, only: :destroy
end
我强制用户更改密码,但它多次抛出重定向错误
1)
class ApplicationController < ActionController::Base
before_action :check_password, if: :current_user # this is why you're getting multiple redirect.
def check_password
if current_user.present? &&
current_user.try(:created_at).try(:to_datetime) ==
current_user.try(:password_changed_at).try(:to_datetime)
redirect_to change_password_admin_user_path(current_user)
end
end
end
所以,请不要这样使用。
如何将 check_password 方法移动到另一个控制器?
例如
class DashboardController < ActionController::Base
def dashboard
if current_user.present? &&
current_user.try(:created_at).try(:to_datetime) ==
current_user.try(:password_changed_at).try(:to_datetime)
redirect_to change_password_admin_user_path(current_user)
end
end
end
此外,除非他更改了密码,否则不要显示任何菜单。
根据您的评论,您正在使用 devise-security gem, so you can use the method need_change_password! (which will clear password_changed_at
) right after the user sign-up, so that the devise hook password_expirable 将检查并强制新用户更改通过,您无需自己处理此逻辑。