写在前面:
ruby-version: 2.1.1
rails-version: 4.1.1
一.model
class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :name
      t.text :password
      t.integer :role_id
      t.timestamps
    end
  end
end
class CreateRoles < ActiveRecord::Migration
  def change
    create_table :roles do |t|
      t.string :name
      t.text :desc
      t.timestamps
    end
  end
end
二.login logout
class SessionsController < ApplicationController
  layout "user", :only => :new
  skip_before_action :require_login, only: [:new, :create]
  def new
    @session = User.new
  end
  def create
    @user = User.authentication(login_params["netid"], login_params["password"])
    if @user
      session[:user_id] = @user.id
      flash[:notice] = "welcome #{@user.name}"
      redirect_to users_path
    else
      flash[:notice] = "pass or netid incorrect"
      redirect_to login_path
    end
  end
  def destroy
    session[:user_id] = nil
    redirect_to login_path
  end
  private
  def login_params
    params.require(:user).permit(:netid, :password)
  end
end
userModel 里面的两个方法
class User < ActiveRecord::Base
  belongs_to :role
  def self.hash_password(pass, name)
    salt = name
    Digest::SHA256.hexdigest(pass + salt)
  end
  def self.authentication(netid, pass)
    user = User.find_by(netid: netid)
    if user && Digest::SHA256.hexdigest(pass + user.name) == user.password
      return user
    end
    false
  end
end
三。实现 current_user,我用的是 help_method
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  private
  def current_user
    @current_user = User.find_by id: session[:user_id] if session[:user_id]
  end
  helper_method :current_user
end
四。实现某些控制器需要登陆
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :require_login
  private
  def current_user
    @current_user = User.find_by id: session[:user_id] if session[:user_id]
  end
  def require_login
    unless current_user
      flash[:notice] = "please login"
      redirect_to login_path
    end
  end
  helper_method :current_user
end
不需要的请使用 skip_before_action
class SessionsController < ApplicationController
  layout "user", :only => :new
  skip_before_action :require_login, only: [:new, :create]
  def new
  end
  def create
  end
  def destroy
  end
  private
  def login_params
    params.require(:user).permit(:netid, :password)
  end
end
五。实现权限控制,同样是作为 help_method
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :require_login
  private
  def current_user
    @current_user = User.find_by id: session[:user_id] if session[:user_id]
  end
  def require_login
    unless current_user
      flash[:notice] = "please login"
      redirect_to login_path
    end
  end
  def required_role(need_role)
    role = current_user.role
    role_name = [role.name]
    unless (need_role & role_name) == role_name
      flash[:error] = "u r not permission"
      redirect_to login_path
    end
  end
  helper_method :current_user
  helper_method :required_role
end
在控制器中这样写
class RolesController < ApplicationController
  before_action :set_role, only: [:show, :edit, :update, :destroy]
  before_action  do
    required_role(["admin"])
  end
end
收工。
PS:原本不需要 role 表,但是方便以后扩展处 permission 表,还是留下了。