DevInterface: Comunicato Stampa
  • 11 mag DevInterface
    22:28 - 11 mag 2011 Veneto http://feedproxy.google.com/~r/devinterfaceblog/it/~3/_qlTgWiCnH0/

    Registrazione in due step con Devise

    [** UPDATE: 24/05/2012 **]: Grazie a Kevin Triplettora c’è una pagina sul wiki di Devise che fa riferimento a questo post combinando anche i vari commenti e contributi ricevuti. Visitate la pagina, soprattutto se utilizzate Rails 3 e Devise 2: https://github.com/plataformatec/devise/wiki/How-To:-Two-Step-Confirmation

    Nei miei progetti in Ruby on Rails generalemente utilizzo Devise come gem per l’autenticazione degli utenti.

    Nell’ultima applicazione sviluppata avevo necessità di personalizzare Devise in modo che gli utenti potessero registrarsi fornendo solo l’indirizzo email.

    La password di accesso doveva essere impostata nello step di conferma dell’account.

    Dopo alcuni test, sono giunto alla seguente soluzione.

    1. Per prima cosa ho dovuto sovrascrivere il ConfirmationsController. Quindi nel file routes.rb ho impostato devise perchè utilizzase il mio controller custom (il mio model degli utenti si chiamava Account).

    Ho dovuto sovrascrivere anche il RegistrationsController per personalizzare la pagina di registrazione:

    1
    2
    3
    4
    5
    </p>
    <p>devise_for :accounts, :controllers =&gt; {:confirmations =&gt; "confirmations", :registrations =&gt; "registrations"} do</p>
    <p>put "confirm_account", :to =&gt; "confirmations#confirm_account"</p>
    <p>end</p>
    <p>

    Come vedete ho anche aggiunto un metodo custom, confirm_account che userò nel quarto step, come vedremo tra poco.

    2. A questo punto devo fare in modo di evitare la validazione della password di devise.

    Per questo scopo ho scritto un initializer chiamato devise_customization.rb in /config/initalizers/ come segue:

    1
    2
    3
    4
    </p>
    <p>module Devise</p>
    <p>module Models</p>
    <p>module Validatable

    1
    2
    3
    4
    def password_required?</p>
    <p>false</p>
    <p>end</p>
    <p>

    1
    2
    3
    4
     end</p>
    <p>end</p>
    <p>end</p>
    <p>

    In questo modo ho sovrascritto il modulo validatable di devise skippando la validazione della password.

    3. Il passo successivo è la personalizzazione delle view.

    Poichè utilizzo i miei ConfirmationsController e RegistrationsController custom ho copiato le view standard di devise sotto /views/confirmations/ per le confirmations e sotto /views/registrations/ per le registrations.

    Le ho poi modificate come segue per adattarle al mio workflow di registrazione.

    La view /registrations/new è diventata cosi (utilizzo haml per i layout)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    </p>
    <p>= form_for(resource, :as =&gt; resource_name, :url =&gt; account_registration_path(@account)) do |f|</p>
    <p>= devise_error_messages!</p>
    <p>%p</p>
    <p>= f.label :email</p>
    <p>= f.email_field :email</p>
    <p>%p.clearfix</p>
    <p>= f.submit 'Signup'</p>
    <p>= link_to 'Home', root_url</p>
    <p>%br/</p>
    <p>= render :partial =&gt; 'devise/shared/links'</p>
    <p>

    In questa view ho semplicemente rimosso i campi password e password_confirmation.

    La view /confirmations/show è invece diventata:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    </p>
    <p>= form_for(resource, :url =&gt; confirm_account_path) do |f|</p>
    <p>= devise_error_messages!</p>
    <p>%p</p>
    <p>= f.label :email</p>
    <p>= @account.email</p>
    <p>= f.hidden_field :confirmation_token</p>
    <p>%p</p>
    <p>= f.label :password</p>
    <p>%br/</p>
    <p>= f.password_field :password</p>
    <p>%p</p>
    <p>= f.label :password_confirmation</p>
    <p>%br/</p>
    <p>= f.password_field :password_confirmation</p>
    <p>%p.clearfix</p>
    <p>= f.submit 'Confirm Account'</p>
    <p>= link_to 'Home', root_url</p>
    <p>%br/</p>
    <p>= render :partial =&gt; 'devise/shared/links'</p>
    <p>

    4. Ok, ora che ho definito le mie view è tempo di scrivere il nuovo metodo di conferma dell’account nel ConfirmationsController. Posso invece lasciare inalterato il RegistrationsController.

    1
    2
    3
    4
    5
    6
    7
    8
    </p>
    <p>class ConfirmationsController &lt; Devise::ConfirmationsController</p>
    <p>def show</p>
    <p>@account = Account.find_by_confirmation_token(params[:confirmation_token])</p>
    <p>if !@account.present?</p>
    <p>render_with_scope :new</p>
    <p>end</p>
    <p>end

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def confirm_account</p>
    <p>@account = Account.find(params[:account][:confirmation_token])</p>
    <p>if @account.update_attributes(params[:account]) and @account.password_match?</p>
    <p>@account = Account.confirm_by_token(@account.confirmation_token)</p>
    <p>set_flash_message :notice, :confirmed</p>
    <p>sign_in_and_redirect("account", @account)</p>
    <p>else</p>
    <p>render :action =&gt; "show"</p>
    <p>end</p>
    <p>end</p>
    <p>

    1
    2
    end</p>
    <p>

    Il metodo show semplicemente si occupa di trovare l’account in base al token ricevuto e poi renderizzza la view show.

    Il punto chiave è il metodo confirm_account dove viene trovato l’account, eseguito l’update dei suoi attributes e se il metodo password_match? ritorna true allora l’account viene confermato chiamando il metodo standard di devise confirm_by_token

    5. L’ultima cosa che rimane da fare è definire il metodo password_match? all’interno del model Account.

    1
    2
    3
    </p>
    <p>class Account &lt; ActiveRecord::Base</p>
    <p>...

    1
    2
    3
    4
    5
    6
    def password_match?</p>
    <p>self.errors[:password] &lt;&lt; 'password not match' if password != password_confirmation</p>
    <p>self.errors[:password] &lt;&lt; 'you must provide a password' if password.blank?</p>
    <p>password == password_confirmation and !password.blank?</p>
    <p>end</p>
    <p>

    1
    2
    end</p>
    <p>

    E questo è tutto!

    Ora potete riavviare il server rails e registrarvi nella vostra applicazione scegliendo la password solo in fase di conferma dell’account.

    Related Post

Coobiz.it - 2024
Social Network | Trova aziende