Rails Tutorial — 9.3.3 Current_User

喜欢而已 提交于 2020-01-10 03:21:06

问题


So I'm following the Rails Tutorial, and I've gotten to the portion where we want to sign a user in with a sign_in SessionHelper.

Question 1:

  module SessionsHelper

  def sign_in(user)
    cookies.permanent.signed[:remember_token] = [user.id, user.salt]
    current_user = user
  end

  def current_user=(user) #set current_user
    @current_user = user
  end

  def current_user #get current_user
    @current_user
  end

What I'm having difficulty with is the part that reads:

The problem is that it utterly fails to solve our problem: with the code the user's signin status would be forgotten: as soon as the user went to another page.

I don't understand how this is true? I read on and understand the added code makes sure @current_user is never nil. But I'm not seeing how current_user would revert to nil if we just established it in 5th line.

Question 2:

The updated code reads as such:

module SessionsHelper

  def sign_in(user) #in helper because used in view & controller
    cookies.permanent.signed[:remember_token] = [user.id, user.salt]
    current_user = user
  end

  def current_user=(user) #set current_user
    @current_user = user
  end

  def current_user #get current_user
    @current_user ||= user_from_remember_token #<-- short-circuit evaluation
  end

  private

    def user_from_remember_token
      User.authenticate_with_salt(*remember_token) #*=use [] instead of 2 vars
    end

    def remember_token
      cookies.signed[:remember_token] || [nil, nil]
    end
end

In the remember_token helper, why does it use cookies.signed[] instead of cookies.permanent.signed[] & why doesn't it use ||= operator we just learned about?

Question 3:

Why do we need to authenticate_with_salt? If I authenticate & sign_in can see the id & salt attributes from the user who was passed to it, why do we need to double_check it? What kind of situation would trigger a mixup?


回答1:


Remember that instance variables like @current_user are only set for the duration of the request. The controller and view handler instances are created specifically for rendering once and once only.

It is often easy to presume that because you've set a variable somewhere that it will continue to work at some point in the future, but this is not the case. To preserve something between requests you need to store it somewhere, and the most convenient place is the session facility.

What's missing in this example is something along the lines of:

def current_user
  @current_user ||= User.find_by_remember_token(cookies[:remember_token])
end

Generally it's a good idea to use the write accessor to map out the functionality of the sign_in method you've given as an example:

def current_user=(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  @current_user = user
end

It's odd that there is a specific "sign in" method when the act of assigning the current user should be the same thing by implication.

From a matter of style, though, it might be more meaningful to call these methods session_user as opposed to current_user for those situations when one user is viewing another. "Current" can mean "user I am currently viewing" or "user I am currently logged in as" depending on your perspective, which causes confusion. "Session" is more specific.

Update:

In response to your addendum, the reason for using cookies to read and cookies.permanent to assign is much the same as using flash.now to assign, and flash to read. The .permanent and .now parts are intended to be used when exercising the assignment operator.



来源:https://stackoverflow.com/questions/5575188/rails-tutorial-9-3-3-current-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!