写在前面:
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 表,还是留下了。