Como usar devise con rails 3 +

Por Boris Barroso

Bueno como les había mostrado en mi anterior post les mostraría en un futuro post como usar devise, devise es una gema para realizar la auntenticación que tiene similitudes con clearance, como dicen es un full stack authentication system, esto quiere decir que no solo permite la autenticación de los usuarios sino que tambien se encarga de permitir cambiar la contrseña en caso de que se hayan olvidado y además de realizar la activación de la cuenta mediante email. Disponer de toda esta funcionalidad sin tener que programarla y testearla es algo muy positivo ya que casí la mayoría de los proyectos necesitan algún tipo de autenticación, activación y recuperación de cuentas. Comencemos creando un proyecto con rails 3 beta.

rails devise_test
cd devise_test

Ahora mdifiquemos el archivo Gemfile para aumentar la gema de devise

gem "devise", "1.1.pre4"

Ahora ejecutemos el comando de instalación

bundle install

Y usamos el generador de devise que crea varios archivos.

rails generate devise_install

Esto nos genera los archivos de configuración asi como los archivos para la traducción. Por defecto devise utiliza la clase User para poder funcionar, pero puede funcionar con una clase con distinto nombre, generemos ahora el modelo usuario para trabajar.

rails generate usuario nombre:string apellido:string

No es necesario crear ni login, email y password ya que devise se encarga de realizar todo esto solo deben ahora editar el archivo de migración que crea la tabla de usuarios de la siguiente forma

  create_table :users do |t|
    t.string :nombre
    t.string :apellido
    t.authenticatable
    t.confirmable
    t.recoverable
    t.rememberable
    t.trackable
    t.timestamps
  end

Y ahora modifiquemos el modelo Usuario

class Usuario < ActiveRecord::Base
  devise :authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
end

Y ahora debemos cbemos configurar las rutas para que puedan acceder correctamente, en el archivo config/routes.rb

 devise_for :users, :as => "usuarios"

Listo, pero aún no podremos probar efectivamente esta herramienta si es que no tenemos configurada nuestra salida smtp para enviar emails, entonces creamos el archivo config/initializers/mail_setup.rb

ActionMailer::Base.smtp_settings = {
  :address => "smtp.gmail.com",
  :port => "587",
  :domain => "midominio.com",
  :user_name => "mi.login.gmail",
  :password => "mi.password",
  :authentication => "plain",
  :enable_starttls_auto => true
}

ActionMailer::Base.default_url_options[:host] = “localhost:3000″

Ahora creamos el formulario de inscripción de un usuario views/usuarios/new.html.erb

<% form_for @user do |f| -%>

  <%= f.label :nombre, "Nombre"
  <%= f.text_field :nombre %>

  <%= f.label :apellido, "Apellido" %>
  <%= f.text_field :apellido %>

  <%= f.label :password, "Contraseña" %>
  <%= f.text_field :password %>

  <%= f.label :password_confirmation, "Confirmar contraseña" %>
  <%= f.text_field :password_confirmation %>

  <%= f.submit "Registrarse" %>
<% end -%>

Y si creamos el usuario recibiremos una confirmación en el correo que hayamos ingresado. Para poder loguear deben ir a usuarios/sign_in, para salir a usuarios/sign_out, aunque esto puede ser configurado en las rutas, aquí un ejemplo de la página oficial

  devise_for :users, :as => "usuarios", :path_names => { :sign_in => 'login', :sign_out => 'logout', :sign_up => 'register', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock' }

Una nota importante es de que devise por defecto no define los atributos attr_accessible y attr_protected entonces es labor de uno definir los mismos en el modelo de la siguiente forma.

class Usuario < ActiveRecord::Base
  devise :authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable
  attr_accessible :email, :password, :password_confirmation # Todos los campos que sean accesibles
end

9 comentarios en “Como usar devise con rails 3”

  1. Gracias por tan buen sitio, sobre todo en español.
    Les comento que trate de montar la gema, y necesito activar la cuenta por email y no me envia correos para esto, que podrá ser? segui las instrucciones al pie de la letra. trabajo con ruby 1.8.7 y rails 2.3.5 y utilizo una cuenta de gmail.

    gracias

  2. la cuenta de email a la que te refieres es para enviar o recibir? si es el caso de enviar te recomiendo que veas como enviar emails mediante tls, el protocolo de seguridad extra para el envío de mail, puedes ver la gema en aqui http://github.com/openrain/action_mailer_tls , si no es asi te sugiero que veas mediante que tipo de sistema estas enviando y si lo tienes bien configurado, si es una cuenta de smtp fíjate que los datos de usuario y contraseña sean los correctos, y por ultimo la ultima opción aunque algo indeseable es utilizar sendmail.
    Espero que te ayude.

  3. Perdón recientemente me di cuenta de que tengo comentados el user_name y password del archivo de configuración config/initializers/mail_setup.rb, quiza ese sea el problema que existe, perdón por el error que ya fue corregido.

  4. hola me quedaron algunas dudas, cuales serian las diferencias en el metodo si uso rails 2 en vez del 3…todavia somos muchos quienes usamos rails 2…otra cosa…aqui no habria que escribir uno mismos las templates con el mensaje que se enviara por correo al registrarse, como se hacia con restfull?…no tengo que llamar al control mailer y hacer el modelo y toda esa cosa?…lo ultimo es que no me quedo del todo claro el ultimo punto..todos los campos los debo hacer accesibles?…gracias!!

  5. hola, soy el mismo que escribio arriba, disculpa la insistencia, estuve probando uno de las aplicaciones de muestras de devise, aun no logro enviarme el correo aunque estoy casi seguro que lo configure bien (como uso rails 2 iria la config en development no?), esto seria lo que escribi:

    config.action_mailer.delivery_method = :smtp
    config.action_mailer.smtp_settings = {
    :enable_starttls_auto => true,
    :address => ’smtp.gmail.com’,
    :port => 587,
    :authentication => :plain,
    :domain => ‘myapp.com’,
    :user_name => ‘micorreo@gmail.com’,
    :password => ‘mipass’
    }

    tambien probe con tu configuracion de mail setup aunque supongo que lo de base es algo de rails 3…no me funciono

    lo curioso es que si bien no puedo confirmar el mail, puedo entrar en la aplcacion, salirme y volver a entrar, es esto normal o es que al no haber configurado el correo bien no lo toma en cuenta, la aplicacion de muestra tiene devise :confirmable pero al parecer no esta funcionand, espero me puedas ayudar, gracias…de nuevo

  6. El articlo esta dirigido a rails3, aunque tambien use devise con rails 2 y no recuerdo donde esta la aplicación que hice funcionar con esto. En cuanto la encuetre lo subo al github y te doy el URL (Espero encontrarla). Lo que tal ves sucede es que no habilitaste el modulo de confirmacion del email, seria que verifiques, sin embargo tal ves esto te sirva de ejemplo, solo lo pones en el config/environments/development.rb

    ActionMailer::Base.smtp_settings = {
    :address => “smtp.gmail.com”,
    :port => “587″,
    :domain => “tudominio”,
    :user_name => “tuusuario”,
    :password => “tupasword”,
    :authentication => “plain”,
    :enable_starttls_auto => true
    }

  7. hola, gracias por responder, todo los modulos parecen estar activos pero creo que el problema es en otro lado, mi duda es si usando esta gema no es necesario usar generate mailer…definir los metodos, llenar el layout y todas esas cosas?…supongo que si no?…espero que puedas conseguir esa aplicacion que hicistes con rails 2 a ver si puedo entender como funciona bien esto…gracias

  8. Hola quisiera saber como hago para que el sing_up sea solo accesible por un solo usuario administrador

  9. Es simple, lo que debes hacer es copiar el controlador de devise a tu directorio, puedes ver el mismo en esta direccion
    http://github.com/plataformatec/devise/blob/master/app/controllers/devise/registrations_controller.rb

    y en este aumentas un metodo que solo permita ingresar al admin con un

    before_filter :autenticar_admin

    def autenticar_admin
    if current_user.rol != ‘admin’
    redirect_to “/”, :notice => ‘Solo admins’
    end
    end

Su comentario