#002 User Authentication

| 21 minutes | 用户验证 入门
在不使用任何现成Authentication gem的前提下,建立一个简单灵活的用户验证机制。本期内容是基于第一期Blog例子。

Create User migration:

db/migrate/20111214073443_create_users.rb
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :login
      t.string :hashed_password
      t.string :salt

      t.timestamps
    end
  end
end

User 模型:

app/models/user.rb
class User < ActiveRecord::Base
  validates :login, :presence => true
  
  def password
    @password
  end
  
  def password=(pass)
    return unless pass
    @password = pass
    generate_password(pass)
  end
  

  # 此处用动词形式(authenticate)更加合适, 特此说明一下. 感谢 Chen Kai 同学的提醒.
  def self.authentication(login, password)
    user = User.find_by_login(login)
    if user && Digest::SHA256.hexdigest(password + user.salt) == user.hashed_password
      return user
    end
    false
  end
  
  private
  def generate_password(pass)
    salt = Array.new(10){rand(1024).to_s(36)}.join
    self.salt, self.hashed_password = 
      salt, Digest::SHA256.hexdigest(pass + salt)
  end
end

Sessions 控制器:

app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
  end
  
  def create
    @user = User.authentication(params[:login], params[:password])
    if @user
      session[:user_id] = @user.id
      flash[:notice] = "Weclome #{@user.login}"
      redirect_to posts_path
    else
      flash[:notice] = "The login or password is not correct."
      redirect_to new_session_path
    end
  end
end

登陆页面

app/views/sessions/new.html.erb
<h1>Admin Login</h1>
<%= form_tag sessions_path do -%>
  <label for="login">Login</label>
  <%= text_field_tag :login, params[:login] %>
  <label for="password">Password</label>
  <%= password_field_tag :password, params[:password] %>
  
  <%= submit_tag "Login"%>
<% end %>
Similar Episodes