vkill'blog

“技术本身没有太多价值,掌握了新的思考方式才是真的收获”

rails 实现认证--使用过滤器

11:57 , vkill
问题:当用户使用某控制器之前需先对他们进行认证,将未认证的用户重定向到登陆界面,认证ok后可以在此控制器下任意操作,可以自由退出登陆
实现:利用会话session,
缺点:关闭网页后认证失效
关键字:before_filter ,session ,request.request_uri
参考自:rails cookbook 书一案例
环境:InstantRails-2.0-win

1、创建rails工程及数据库

rails auth_test -d sqlite3
cd auth_test
rake db:create:all

2、建立一个用户数据库来保存帐户信息

ruby script\generate model users name:string hash_pass:string
rake db:migrate

3、新增一个用户

ruby script\console
Loading development environment (Rails 2.0.2)
>> hash_pass=Digest::MD5.hexdigest("123456")
=> "e10adc3949ba59abbe56e057f20f883e"
>> Users.create :name=>"admin" ,:hash_pass=>"#{hash_pass}"
=> #<Users id: 1, name: "admin", hash_pass: "e10adc3949ba59abbe56e057f20f883e", created_at: "2008-01-21 20:21:13", updated_at: "2008-01-21 20:21:13">
>> exit

4、创建一个控制器来处理新用户的登陆、验证和登出
ruby script\generate controller user login logout verify

修改登陆表单模板app\views\user\login.html.erb如下

<h1>User#login</h1>
<%= h(flash['notice']) %>
<% form_tag 'verify' do %>
  username:<%= text_field :user , :username ,:size => '20' %>
  <p>
  userpass:<%= password_field :user , :userpass ,:size => '22' %>
  <p>
  <%= submit_tag "Login" %>
<% end %>

修改app\controllers\user_controller.rb如下

require 'digest/md5'
class UserController < ApplicationController
  def login
  end
  def verify
    hash_pass = Digest::MD5.hexdigest(params[:user][:userpass])
    user = Users.find(:first , :conditions => ["name=? and hash_pass=?",params[:user][:username],hash_pass ] )
    if not user
      #有时候我们手动添加用户到数据库的时候可能添加的md5值中字母是全大写的,这时就需要 .swapcase 来帮忙了
      user = Users.find(:first , :conditions => ["name=? and hash_pass=?",params[:user][:username],hash_pass.swapcase ] )
    end
    if user
      session['user'] = user
      redirect_to session['last_url']
      else
        flash['notice'] = '错误的 userpass/userpass'
        redirect_to :controller => 'user' , :action => 'login'
    end
  end
  def logout
    reset_session
    redirect_to :controller => 'testposts'
  end
end

5、定义一个auth方法来检查用户是否登陆,修改app\controllers\application.rb文件如下

class ApplicationController < ActionController::Base
  helper :all
  protect_from_forgery
  #定义一个auth方法来检查用户是否登陆,并保存用户最初请求的URL
  def auth
    if session['user'].nil?
      session['last_url'] = request.request_uri
      redirect_to :controller => 'user' , :action => 'login'
    end
  end
end

6、新建需要认证的控制器(测试用)testpost

ruby script/generate scaffold testpost title:string body:text
rake db:migrate

修改app\controllers\testposts_controller.rb如下,(添加 before_filter :auth)

Class TestpostsController < ApplicationController
  before_filter :auth
  #下面的这个只对该控制器下的edit和destroy方法生效
#before_filter :auth, :only => [:edit, :destroy]
  def index
......

在app\views\testposts\index.html.erb最后添加一个“退出登陆”的link

<%= link_to '退出登陆', :controller => 'user' , :action => 'logout' %>

7、启动server且浏览测试

start ruby script\server -p 3000
start http://127.0.0.1:3000/testposts

这时已经自动重定向到http://127.0.0.1:3000/user/login页面,输入 admin/123456 登陆就可以了

附件:
rails_apps-auth_test 工程打包

Last modified by vkill on2008/06/30 20:14
类别:ruby & rails | Tags: , , , , | 0 条评论, 2311 次阅读
网友评论(0):
发表评论:

Nickname: 
Email:
Site URI: