读书人

netzke 施用 authlogic 做登录验

发布时间: 2012-12-18 12:43:41 作者: rapoo

netzke 使用 authlogic 做登录验证

= 使用 authlogic 做登录验证

== 在Gemfile中添加authlogic相关的gems

? gem 'authlogic'
? gem 'rails3-generators'
? gem 'dynamic_form'

== 本地安装gems
? gem install -l --no-ri --no-rdoc authlogic-2.1.6.gem

== 执行 bundle install 或者 bundle update.

== 创建UserSession

rails g authlogic:session UserSession
????? create? app/models/user_session.rb
????? invoke? test_unit
????? create??? test/unit/user_session_test.rb
????? create??? test/fixtures/user_sessions.yml

== 修正错误

* 在UserSession添加代码
app/models/user_session.rb
? class UserSession < Authlogic::Session::Base
??? def to_key
????? new_record? ? nil : [ self.send(self.class.primary_key) ]
??? end
? end

== 创建用户模型 User model

rails g model User
????? invoke? active_record
????? create??? db/migrate/20110116013856_create_users.rb
??? conflict??? app/models/user.rb
? Overwrite app/models/user.rb? (enter "h" for help) [Ynaqdh] y
?????? force??? app/models/user.rb
????? invoke??? test_unit
????? create????? test/unit/user_test.rb
????? create????? test/fixtures/users.yml

== 创建角色模型 Role model

rails g model Role
????? invoke? active_record
????? create??? db/migrate/20110116042653_create_roles.rb
??? conflict??? app/models/role.rb
? Overwrite app/models/role.rb? (enter "h" for help) [Ynaqdh] y
?????? force??? app/models/role.rb
????? invoke??? test_unit
????? create????? test/unit/role_test.rb
????? create????? test/fixtures/roles.yml

?????
== 修改 CreateUsers migration

db/migrate/20110116013856_create_users.rb
? class CreateUsers < ActiveRecord::Migration
??? def self.up
????? create_table :users do |t|
??????? t.string??? :login,?????????????? :null => false
??????? t.integer?? :role_id,???????????? :null => false
??????? t.string??? :email,?????????????? :null => false
??????? t.string??? :crypted_password,??? :null => false
??????? t.string??? :password_salt,?????? :null => false
??????? t.string??? :persistence_token,?? :null => false
??????? t.string??? :single_access_token, :null => false??????????????? # optional, see Authlogic::Session::Params
??????? t.string??? :perishable_token,??? :null => false??????????????? # optional, see Authlogic::Session::Perishability
??
??????? # magic fields (all optional, see Authlogic::Session::MagicColumns)
??????? t.integer?? :login_count,???????? :null => false, :default => 0
??????? t.integer?? :failed_login_count,? :null => false, :default => 0
??????? t.datetime? :last_request_at
??????? t.datetime? :current_login_at
??????? t.datetime? :last_login_at
??????? t.string??? :current_login_ip
??????? t.string??? :last_login_ip
??????? t.timestamps
????? end
??
????? add_index :users, ["login"], :name => "index_users_on_login", :unique => true
????? add_index :users, ["email"], :name => "index_users_on_email", :unique => true
????? add_index :users, ["persistence_token"], :name => "idx_users_persistence", :unique => true
??
??? end
???
??? #User.create(:login => 'admin', :password => 'admin', :password_confirmation => 'admin', :role_id => 1)
??
??? def self.down
????? drop_table :users
??? end
? end

* Persistence token: 是authlogic的持久性标记,将会存储在浏览器的Cookie中,远远比将用户id存在Cookie中安全。
* Perishable token: 用于审核或者重新设置密码

== 修改 CreateRoles migration

db/migrate/20110116042653_create_roles.rb
? class CreateRoles < ActiveRecord::Migration
??? def self.up
????? create_table :roles do |t|
??????? t.string :name
?
??????? t.timestamps
????? end
?????
????? Role.create(:name => 'administrator')
??? end
?
??? def self.down
????? drop_table :roles
??? end
? end

== 执行创建表

rake db:migrate

== 修改User model

app/models/user.rb
? class User < ActiveRecord::Base
??? belongs_to :role
??? acts_as_authentic
???
??? attr_accessor :old_password
?
??? validate :validate_old_password, :if => :required_old_password?
???
??? def validate_old_password
????? errors.add(:old_password) unless valid_password?(self.old_password)
??? end
?
??? def required_old_password!
????? @old_password_required = true
????? @password_changed = true
??? end
?
??? def required_old_password?
????? @old_password_required
??? end
?
??? def active_recently?
????? last_request_at && last_request_at > 1.day.ago
??? end
???
??? def self.find_by_login(login)
????? find(:first, :conditions => ["LOWER(login) = ?", login.to_s.downcase])
??? end
???
??? def self.most_active(role)
????? select = "users.*"
????? find(:all, :conditions => ["role_id = ?", role], :limit => 13, :select => select, :order => 'login_count DESC')
??? end
???
??? netzke_attribute :password
??? netzke_attribute :password_confirmation
? end

== 修改Role model

app/models/role.rb
? class Role < ActiveRecord::Base
??? has_many :users
? end

== 修改 ApplicationController

app/controllers/application_controller.rb
? class ApplicationController < ActionController::Base
??? protect_from_forgery
??? layout 'application'
??? helper_method :current_user_session, :current_user
??
??? private
????? def current_user_session
??????? logger.debug "ApplicationController::current_user_session"
??????? return @current_user_session if defined?(@current_user_session)
??????? @current_user_session = UserSession.find
????? end
??
????? def current_user
??????? logger.debug "ApplicationController::current_user"
??????? return @current_user if defined?(@current_user)
??????? @current_user = current_user_session && current_user_session.user
????? end
??
????? def require_user
??????? logger.debug "ApplicationController::require_user"
??????? unless current_user
????????? store_location
????????? flash[:notice] = "You must be logged in to access this page"
????????? redirect_to new_user_session_url
????????? return false
??????? end
????? end
??
????? def require_no_user
??????? logger.debug "ApplicationController::require_no_user"
??????? if current_user
????????? store_location
????????? flash[:notice] = "You must be logged out to access this page"
????????? redirect_to account_url
????????? return false
??????? end
????? end
??
????? def store_location
??????? session[:return_to] = request.request_uri
????? end
??
????? def redirect_back_or_default(default)
??????? redirect_to(session[:return_to] || default)
??????? session[:return_to] = nil
????? end
? end

== 创建UserSessionsController 控制用户登陆 退出

rails g controller UserSessions new
????? create? app/controllers/user_sessions_controller.rb
?????? route? get "user_sessions/new"
????? invoke? erb
????? create??? app/views/user_sessions
????? create??? app/views/user_sessions/new.html.erb
????? invoke? test_unit
????? create??? test/functional/user_sessions_controller_test.rb
????? invoke? helper
????? create??? app/helpers/user_sessions_helper.rb
????? invoke??? test_unit
????? create????? test/unit/helpers/user_sessions_helper_test.rb

=== 修改登陆控制 user_sessions_controller.rb

app/controllers/user_sessions_controller.rb
? class UserSessionsController < ApplicationController
??? before_filter :require_no_user, :only => [:new, :create]
??? before_filter :require_user, :only => :destroy
???
??? def new
????? @user_session = UserSession.new
??? end
???
??? def create
????? @user_session = UserSession.new(params[:user_session])
????? if @user_session.save
??????? flash[:notice] = "Login successful!"
??????? redirect_back_or_default root_url
????? else
??????? render :action => :new
????? end
??? end
???
??? def destroy
????? current_user_session.destroy
????? flash[:notice] = "Logout successful!"
????? redirect_back_or_default new_user_session_url
??? end
???
? end

=== 修改登陆视图 new.html.erb

app/views/user_sessions/new.html.erb
? <h2>Welcome Login</h2>
?
? <% form_for @user_session, :url => user_session_path do |f| %>
??? <%= f.label :login %><br />
??? <%= f.text_field :login %><br />
??? <%= f.label :password %><br />
??? <%= f.password_field :password %><br />
??? <%= f.check_box :remember_me %><%= f.label :remember_me,"Remember Me " %><%= link_to "Register", new_user_url %>
??? <div class='align-right bottom borderd'>
????? <div class='left'><%= flash[:notice] %></div>
????? <div class='right'><input src="/images/backend/btn-login.png" type="image" /></div>???
????? <div class='clear'></div>
??? </div>?
??? <br />?
??? <%= f.error_messages %>
? <% end %>

== 创建UsersController 注用户

rails g controller Users new
????? create? app/controllers/users_controller.rb
?????? route? get "users/new"
????? invoke? erb
????? create??? app/views/users
????? create??? app/views/users/new.html.erb
????? invoke? test_unit
????? create??? test/functional/users_controller_test.rb
????? invoke? helper
????? create??? app/helpers/users_helper.rb
????? invoke??? test_unit
????? create????? test/unit/helpers/users_helper_test.rb
?????
=== 修改用户注控制

app/controllers/users_controller.rb
? class UsersController < ApplicationController
??? def new???
????? @user = User.new
????? # render? :layout => 'user_sessions'
??? end
??? def create
????? @user = User.new(params[:user].merge(:role => Role.find_by_name('administrator')))
????? if @user.save
??????? flash[:notice] = "Registration successful."
??????? redirect_back_or_default root_url
????? else
??????? render :action => :new
????? end
??? end
?
? end?

=== 修改用户注视图

app/views/users/new.html.erb
? <h3>New User</h3>
?
? <% form_for @user, :url => user_path do |f| %>
??? <%= f.error_messages %>?
??? <%= render :partial => "form", :object => f %>
??? <%= f.submit "Submit" %>
? <% end %>

=== 增加用户注视图

app/views/users/_form.html.erb
? <%= form.label :login %><br />
? <%= form.text_field :login %><br />
? <br />
? <%= form.label :email %><br />
? <%= form.text_field :email %><br />
? <br />
? <%= form.label :password, form.object.new_record? ? nil : "Change password" %><br />
? <%= form.password_field :password %><br />
? <br />
? <%= form.label :password_confirmation %><br />
? <%= form.password_field :password_confirmation %><br />
? <br />

== 修改布局视图

=== public增加图片和css文件

* 相文件附件.
? public/images/backend
? public/stylesheets/standard.css
? public/stylesheets/login.css

=== 登陆布局视图

app/views/layouts/user_sessions.html.haml
? !!!
? %html
??? %head
????? %title="Login"
????? =stylesheet_link_tag "standard", "login"
??? %body
????? #wrapper
??????? #login-box
????????? #content
??????????? =yield
??????? #copyright
????????? Copyright © 2011 President office of the 3rd division All rights reserved

=== 用户注布局视图

app/views/layouts/users.html.erb
? <head>
??? <meta http-equiv="Content-type" content="text/html; charset=utf-8">
??? <title>Register<title>
? </head>
? <body>
??? <%= yield %>
? </body>

== 修改routes.rb

? NetzkeDemo::Application.routes.draw do
??? # AuthLogic
??? resource :user_session
??? resource :user
??? match 'login' => "user_sessions#new",????? :as => :login
??? match 'logout' => "user_sessions#destroy", :as => :logout?
? end?

== 控制登陆访问

app/controllers/demo_controller.rb
? class DemoController < ApplicationController
??? layout "application"
??? before_filter :require_user
??? def index
????? render :inline => "<% title 'Demo App', false %><%= netzke :some_simple_app %>", :layout => true
??? end
? end

== 登陆用

SimpleApp改AuthApp, menu承SimpleApp
app/components/some_simple_app.rb
? class SomeSimpleApp < Netzke::Basepack::AuthApp
?
??? # Extend SimpleApp#menu
??? def menu
????? ["->", :about.action] + super
??? end
?
== authlogic警告

? DEPRECATION WARNING: save(false) is deprecated, please give save(:validate => false) instead.?
?
修改的文件如下:
* lib/authlogic/session/callbacks.rb: 将save_without_session_maintenance(false)改为save_without_session_maintenance(:validate => false)?
* lib/authlogic/acts_as_authentic/password.rb: 将save(false)改为save(:validate => false)
* lib/authlogic/acts_as_authentic/logged_in_status.rb: 将named_scope改为scope

读书人网 >编程

热点推荐