2014-10-27 75 views
0

我正在通過Hartl的Ruby on Rails教程(第3版)進行工作,並剛剛完成了第8章。本章的目標之一是讓應用程序通過刪除會話的用戶ID並從瀏覽器。但是,我已註銷應用程序,然後在瀏覽器中輸入http://localhost:3000/users/1,並已被帶回用戶1的配置文件。這是安全問題嗎?第8章 - 可能繞過登錄?

登錄屏幕: the log in screen

登錄:

logged in

註銷,直接返回到主頁: enter image description here

現在,這裏是我米困惑。如果我在用戶鍵入/ 1在瀏覽器的地址欄中,我彷彿被帶回用戶#1的網頁,雖然右上角不顯示我的登錄狀態。

enter image description here

有誰認爲這是一個安全問題?

下面是一些與該應用程序相關的代碼。我錯過了什麼嗎?

users_controller.rb

class UsersController < ApplicationController 

    def show 
    @user = User.find(params[:id]) 
    end 

    def new 
    @user = User.new 
    end 

    def create 
    @user = User.new(user_params) 
    if @user.save 
     log_in @user 
     flash[:success] = "Welcome to the Sample App!" 
     redirect_to @user 
    else 
     render 'new' 
    end 
    end 

    def edit 
    @user = User.find(params[:id]) 
    end 

    private 

    def user_params 
     params.require(:user).permit(:name, :email, :password, 
            :password_confirmation) 
    end 

end 

sessions_controller.rb

class SessionsController < ApplicationController 

    def new 
    end 

    def create 
    @user = User.find_by(email: params[:session][:email].downcase) 
    if @user && @user.authenticate(params[:session][:password]) 
     log_in @user 
     params[:session][:remember_me] == '1' ? remember(@user) : forget(@user) 
     redirect_to @user 
    else 
     flash.now[:danger] = 'Invalid email/password combination' 
     render 'new' 
    end 
    end 

    def destroy 
    log_out if logged_in? 
    redirect_to root_url 
    end 
end 

sessions_helper.rb

module SessionsHelper 

    # Logs in the given user. 
    def log_in(user) 
    session[:user_id] = user.id 
    end 

    # Remembers a user in a persistent session. 
    def remember(user) 
    user.remember 
    cookies.permanent.signed[:user_id] = user.id 
    cookies.permanent[:remember_token] = user.remember_token 
    end 

    # Returns the user corresponding to the remember token cookie. 
    def current_user 
    if (user_id = session[:user_id]) 
     @current_user ||= User.find_by(id: user_id) 
    elsif (user_id = cookies.signed[:user_id]) 
     user = User.find_by(id: user_id) 
     if user && user.authenticated?(cookies[:remember_token]) 
     log_in user 
     @current_user = user 
     end 
    end 
    end 

    # Returns true if the user is logged in, false otherwise. 
    def logged_in? 
    !current_user.nil? 
    end 

    # Forgets a persistent session. 
    def forget(user) 
    user.forget 
    cookies.delete(:user_id) 
    cookies.delete(:remember_token) 
    end 

    # Logs out the current user. 
    def log_out 
    forget(current_user) 
    session.delete(:user_id) 
    @current_user = nil 
    end 

end 

user.rb

class User < ActiveRecord::Base 
    attr_accessor :remember_token 
    before_save { self.email = email.downcase } 
    validates :name, presence: true, length: { maximum: 50 } 
    VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 
    validates :email, presence: true, length: { maximum: 255 }, 
        format: { with: VALID_EMAIL_REGEX }, 
        uniqueness: { case_sensitive: false } 
    has_secure_password 
    validates :password, length: { minimum: 6 } 

    # Returns the hash digest of the given string. 
    class << self 
    def digest(string) 
     cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : 
                BCrypt::Engine.cost 
     BCrypt::Password.create(string, cost: cost) 
    end 

    # Returns a random token. 
    def new_token 
     SecureRandom.urlsafe_base64 
    end 
    end 

    # Remembers a user in the database for use in persistent sessions. 
    def remember 
    self.remember_token = User.new_token 
    update_attribute(:remember_digest, User.digest(remember_token)) 
    end 

    # Returns true if the given token matches the digest. 
    def authenticated?(remember_token) 
    return false if remember_digest.nil? 
    BCrypt::Password.new(remember_digest).is_password?(remember_token) 
    end 

    # Forgets a user. 
    def forget 
    update_attribute(:remember_digest, nil) 
    end 

end 

感謝。

+0

您所看到的僅僅是顯示用戶個人資料的頁面 - 這裏沒有訪問限制,它不僅限於當前登錄的用戶,或者類似的東西。 – sevenseacat 2014-10-27 01:06:57

+0

是的。得到它了。現在有道理。另外,作者在後面的章節中詳細討論了安全問題。 – 2014-10-31 04:04:17

回答

0

不,現在沒有安全問題。您正在爲/ users/1發出GET請求,並且Rails提供了此請求。沒有任何東西阻止顯示該頁面。

由於sevenseacat在上面的評論中解釋過,所以沒有訪問限制。