今天我们来看看Rails怎么处理登录认证
虽然Rails有很多登录认证的插件,但是我们可以自己动手丰衣足食
1,db/migrate/001_add_user_table.rb
[code]
class AddUserTable < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :username, :string
t.column :password_salt, :string
t.column :password_hash, :string
end
end
def self.down
drop_table :users
end
end
[/code]
2,app/models/user.rb
[code]
class User < ActiveRecord::Base
validates_uniqueness_of :username
def password=(pass)
salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
self.password_salt, self.password_hash = salt, Digest::SHA256.hexdigest(pass + salt)
end
def self.authenticate(username, password)
user = User.find(:first, :conditions => ['username = ?', username])
if user.blank? || Digest::SHA256.hexdigest(password + user.password_salt) != user.password_hash
raise "Username or password invalid"
end
user
end
end
[/code]
3,app/controllers/admin_controller.rb
[code]
class AdminController < ApplicationController
before_filter :check_authentication, :except => [:signin_form, :signin]
def check_authentication
unless session[:user]
session[:intended_action] = action_name
redirect_to :action => :signin_form
end
end
def signin
session[:user] = User.authenticate(params[:username], params[:password]).id
redirect_to :action => session[:intended_action]
end
def signout
session[:user] = nil
redirect_to home_url
end
end
[/code]
4,app/views/sign_form.rhtml
[code]
<html>
<head>
<title>Signin for Admin Access</title>
</head>
<body>
<%= start_form_tag :action => "signin" %>
<label for="username">Username:</label>
<%= text_field_tag "username" %><br/>
<label for="password">Password:</label>
<%= text_field_tag "password" %><br/>
<%= submit_tag "Sign in" %>
<%= end_form_tag %>
</body>
</html>
[/code]
我们也可以将check_authentication方法放到application.rb里面,供其他Controllers使用
虽然Rails有很多登录认证的插件,但是我们可以自己动手丰衣足食
1,db/migrate/001_add_user_table.rb
[code]
class AddUserTable < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :username, :string
t.column :password_salt, :string
t.column :password_hash, :string
end
end
def self.down
drop_table :users
end
end
[/code]
2,app/models/user.rb
[code]
class User < ActiveRecord::Base
validates_uniqueness_of :username
def password=(pass)
salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
self.password_salt, self.password_hash = salt, Digest::SHA256.hexdigest(pass + salt)
end
def self.authenticate(username, password)
user = User.find(:first, :conditions => ['username = ?', username])
if user.blank? || Digest::SHA256.hexdigest(password + user.password_salt) != user.password_hash
raise "Username or password invalid"
end
user
end
end
[/code]
3,app/controllers/admin_controller.rb
[code]
class AdminController < ApplicationController
before_filter :check_authentication, :except => [:signin_form, :signin]
def check_authentication
unless session[:user]
session[:intended_action] = action_name
redirect_to :action => :signin_form
end
end
def signin
session[:user] = User.authenticate(params[:username], params[:password]).id
redirect_to :action => session[:intended_action]
end
def signout
session[:user] = nil
redirect_to home_url
end
end
[/code]
4,app/views/sign_form.rhtml
[code]
<html>
<head>
<title>Signin for Admin Access</title>
</head>
<body>
<%= start_form_tag :action => "signin" %>
<label for="username">Username:</label>
<%= text_field_tag "username" %><br/>
<label for="password">Password:</label>
<%= text_field_tag "password" %><br/>
<%= submit_tag "Sign in" %>
<%= end_form_tag %>
</body>
</html>
[/code]
我们也可以将check_authentication方法放到application.rb里面,供其他Controllers使用