【问题标题】:Why does current_user session become nil when updating a user?为什么更新用户时 current_user 会话变为零?
【发布时间】:2013-08-28 13:30:34
【问题描述】:

我正在使用 Devise 和 CanCan 进行用户身份验证和管理角色,从而限制某些用户访问我的 Rails 4 应用程序的某些部分。

我在更新用户时遇到了一些问题。更新工作正常,数据库中的用户对象得到更新,但我的用户会话在以下redirect_to我的用户显示操作中丢失。 current_user 变为 nil 这意味着 CanCan 限制了对用户显示操作的访问。

为什么更新后current_user 会变成nil,而其他操作(例如创建、销毁等)不会发生这种情况?

这些是我的用户模型中的设计设置:

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:login]

这是我的 users_controller.rb 的更新方法:

class UsersController < ApplicationController

  load_and_authorize_resource
  before_filter :authenticate_user!

  def update
    @user = User.find(params[:id])
    if params[:user][:password].blank?
        params[:user].delete(:password)
    end

    respond_to do |format|
      if @user.update_attributes(user_params)
        format.html { redirect_to user_path, :notice => 'User was successfully updated.' }
        format.json { head :ok }
      else
        format.html { render :action => "edit" }
        format.json { render :json => @user.errors, :status => :unprocessable_entity }
      end
    end
  end
end

这是我的ability.rb文件:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if defined?(user.role_id)
      if user.role? :admin, user.role_id
        can :manage, :all
      elsif user.role? :hauler, user.role_id
        can :manage, [User,Trip,Invoice], user_id: user.id.to_s
      else
        can :create, :Trip
      end
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails devise ruby-on-rails-4 cancan


    【解决方案1】:

    这取决于正在执行的更新。会话使用某些用户数据位进行序列化。

    例如更新密码将导致会话无效,因为加密密码是序列化哈希的一部分,如果更改,会话将无法再引用原始加密密码。

    【讨论】:

    • 谢谢你。如果我在不更新密码的情况下更新用户,重定向工作正常。所以按照你的说法,如果用户更改密码,我需要重新登录,对吗?
    • 是的——特别是sign_in @user, :bypass =&gt; true——你可以在这里看到更多信息:github.com/plataformatec/devise/wiki/…
    【解决方案2】:

    为我工作

    def update
    
        respond_to do |format|
    
          if @user.update(user_params)
    
            sign_in(@user, :bypass=>true)
    
            format.html { redirect_to @user, notice: 'User was successfully updated.' }
            format.json { render :show, status: :ok, location: @user }
    
          else
            format.html { render :edit }
            format.json { render json: @user.errors, status: :unprocessable_entity }
          end
    
        end
    
    end
    

    魔法发生在 :bypass=>true

    【讨论】:

      猜你喜欢
      • 2015-03-05
      • 2011-07-15
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多