Sidslog

Март 11, 2010

Авторизация и подтверждение регистрации в rails-2.3. Authlogic, recaptcha, tlsmail

Filed under: rails, Uncategorized — Метки: , , , , , — sidslog @ 9:06 пп

Добавление authlogic в rails-2.3 проект

1) Добавляем gem’ы authlogic, tlsmail и recaptcha

config.gem ‘authlogic’
config.gem ‘tlsmail’
config.gem ‘recaptcha’

2) Создаем миграцию, в которой добавляем необходимые колонки в таблицу пользователей

add_column :users, :login, :string, :default => ”, :null => false
add_column :users, :email, :string, :default => ”, :null => false
add_column :users, :crypted_password, :string
add_column :users, :password_salt, :string
add_column :users, :persistence_token, :string, :default => ”, :null => false
add_column :users, :single_access_token, :string, :default => ”, :null => false
add_column :users, :perishable_token, :string, :default => ”, :null => false
add_column :users, :login_count, :integer, :default => 0, :null => false
add_column :users, :failed_login_count, :integer, :default => 0, :null => false
add_column :users, :last_request_at, :datetime
add_column :users, :last_login_at, :datetime
add_column :users, :current_login_ip, :string
add_column :users, :last_login_ip, :string
add_column :users, :active, :boolean, :default => false, :null => false
add_column :users, :openid_identifier, :string

3) Создаем модель user_session

script/generate session user_session

4) Создаем контроллер user_sessions

script/generate controller user_sessions

в контроллер помещаем код:

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 account_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

5) Редактируем ApplicationController

class ApplicationController < ActionController::Base
  before_filter :require_user
  helper :all # include all helpers, all the time

  helper_method :current_user_session, :current_user
  filter_parameter_logging :password, :password_confirmation

  private
    def current_user_session
      return @current_user_session if defined?(@current_user_session)
      @current_user_session = UserSession.find
    end

    def current_user
      return @current_user if defined?(@current_user)
      @current_user = current_user_session && current_user_session.record
    end

    def 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
      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

6) Создаем контроллер для Users

script/generate controller users

  skip_before_filter :require_user # Override application wide filter
  before_filter :require_no_user, :only => [:new, :create]
  before_filter :require_user, :only => [:show, :edit, :update, :visit_first, :visit_next, :save_after_visit, :select_company]

  def new
    @user = User.new
  end

  def create
    @user = User.new
    if @user.signup!(params)
      @user.deliver_activation_instructions!
      flash[:notice] = "Your account has been created. Please check your e-mail for your account activation instructions!"

      redirect_to new_user_session_url
    else
      render :action => :new
    end
  end

  def show
    @user = @current_user
    result = get_json
    @lat = result[0]
    @lng = result[1]
  end

  def edit
    @user = @current_user
  end

  def update
    @user = @current_user # makes our views "cleaner" and more consistent
    if @user.update_attributes(params[:user])
      flash[:notice] = "Account updated!"
      redirect_to account_url
    else
      render :action => :edit
    end
  end

В routes.rb добавляем

# config/routes.rb
map.resource :account, :controller => “users”
map.resources :users

7) Создаем контроллер activations

script/generate controller activations new create

В контроллер activations добавляем

  before_filter :require_no_user, :only => [:new, :create]

  def new
    @user = User.find_using_perishable_token(params[:activation_code], 1.week) || (raise Exception)
    raise Exception if @user.active?
  end

  def create
    @user = User.find(params[:id])

    raise Exception if @user.active?

    if @user.activate!(params)
      @user.deliver_activation_confirmation!
      redirect_to account_url
    else
      render :action => :new
    end
  end

8) Добавляем в user.rb

 attr_accessible :login, :email, :password, :password_confirmation, :openid_identifier
 def active?
     active
 end 

  acts_as_authentic do |c|
    c.validates_length_of_password_field_options = {:on => :update, :minimum => 4, :if => :has_no_credentials?}
    c.validates_length_of_password_confirmation_field_options = {:on => :update, :minimum => 4, :if => :has_no_credentials?}
  end # block optional

  def has_no_credentials?
    self.crypted_password.blank? && self.openid_identifier.blank?
  end

  def signup!(params)
    self.login = params[:user][:login]
    self.email = params[:user][:email]
#    self.password = params[:user][:password]
    save_without_session_maintenance
  end

 def activate!(params)
    self.active = true
    self.password = params[:user][:password]
    self.password_confirmation = params[:user][:password_confirmation]
    self.openid_identifier = params[:user][:openid_identifier]

    save
  end

  def deliver_activation_instructions!
    reset_perishable_token!
    Notifier.deliver_activation_instructions(self)
  end

  def deliver_activation_confirmation!
    reset_perishable_token!
    Notifier.deliver_activation_confirmation(self)
  end

9) Создаем Mailer Notifier

class Notifier < ActionMailer::Base 
  def activation_instructions(user)
     subject       "Activation Instructions"
     from          "test@company.com"
     recipients    user.email
     sent_on       Time.now
     body          :account_activation_url => register_url(user.perishable_token)
  end

  def activation_confirmation(user)
    subject       "Activation Complete"
    from          "test@company.com"
    recipients    user.email
    sent_on       Time.now
    body          :root_url => root_url
  end

end

10) В routes.rb добавляем

map.register ‘/register/:activation_code’, :controller => ‘activations’, :action => ‘new’
map.activate ‘/activate/:id’, :controller => ‘activations’, :action => ‘create’

11) В activations/new.html.erb добавляем код:

Activate your account

<% form_for @user, :url => activate_path(@user.id), :html => { :method => :post } do |form| %>
    <%= form.error_messages %>
    <%= render :partial => "form", :locals => { :form => form }%>
    <%= form.submit "Activate" %>
<% end %>

В _form.html.erb добавляем:

<%= form.label :password, "Set your password" %>

<%= form.password_field :password %>

<br />
<%= form.label :password_confirmation %>

<%= form.password_field :password_confirmation %>

<br />
<%= recaptcha_tags  :display => {:theme => 'white'} %>

12) Создаем initializars/mail.rb

if RAILS_ENV != 'test'
#  email_settings = YAML::load(File.open("#{RAILS_ROOT}/config/email.yml"))
#  ActionMailer::Base.smtp_settings = email_settings[RAILS_ENV] unless email_settings[RAILS_ENV].nil?
  require 'tlsmail'

  Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)

  ActionMailer::Base.smtp_settings = {
    :address => 'smtp.example.com',
    :port => 587,
    :enable_starttls_auto => true,
    :domain => 'test.com',
    :authentication => :plain,
    :user_name => 'test@example.com',
    :password => 'password'
  }

  ActionMailer::Base.delivery_method = :smtp
  ActionMailer::Base.default_url_options[:host] = "127.0.0.1"
  ActionMailer::Base.default_url_options[:port] = "3000"
  ActionMailer::Base.raise_delivery_errors = true

end

13) Создаем user_sessions/new.html.erb

<h1>Login

<% form_for @user_session, :url => user_session_path do |f| %>
  <%= f.error_messages %>
  <%= f.label :login %><br />
  <%= f.text_field :login %><br />
  <br />
  <%= f.label :password %><br />
  <%= f.password_field :password %><br />
  <br />
  <%= f.check_box :remember_me %><br />
  <br />
  <%= f.submit "Login" %>
<% end %>

14) Создаем notifier/activation_confirmation.html.erb

<!-- new file app/views/notifier/activation_confirmation.erb -->
Your account has been activated.

<%= @root_url %>

15) Создаем notifier/activation_instructions.html.erb

Thank you for creating an account! Click the url below to activate your account!

<%= @account_activation_url %>

If the above URL does not work try copying and pasting it into your browser. If you continue to have problem, please feel free to contact us.

16) В environment.rb добавляем

ENV['RECAPTCHA_PUBLIC_KEY'] = ’6Lf2cQsAAAAAAINPdVA2lVQ73Wtjfa15z2wbiihc’
ENV['RECAPTCHA_PRIVATE_KEY'] = ’6Lf2cQsAAAAAAISRfXwI3atESGkpeihOSiiB-m0H’

Theme: Silver is the New Black. Блог на WordPress.com.

Follow

Get every new post delivered to your Inbox.