Samstag, 25. September 2010

Authentifizierung leicht gemacht mit Devise/Warden

In jeder Anwendung hat man immer wieder das gleiche Problem: Die Nutzer sollen verschiedene Rechte in der Anwendung haben.

Voraussetzung dafür ist zunächst einmal die Registrierung von Nutzern, am besten noch über eine Bestätigungsmail und die Anmeldung der Nutzer über eine Login-Seite.

Bisher hatte ich dafür Authlogic verwendet. Allerdings wurde das zuletzt vor anderthalb Jahren aktualisiert.

Also machte ich mich auf die Suche nach etwas "Modernerem" und stieß auf Devise.

Auf den ersten Blick machte das einen sehr guten Eindruck, obwohl hier anscheinend mit Codegenerierung gearbeitet wird, was Upgrades prinzipiell erschwert.

Allerdings sind die Features so überzeugend, dass ich es einmal ausprobieren wollte. Dazu gehört die Möglichkeit, mehrere Models an die Authentisierung zu koppeln und damit verschiedene Benutzerrollen in der Anwendung verwenden zu können.

Die aktuelle Version 1.1 funktioniert nur mit Rails 3. Da meine Anwendung noch Rails 2.3.8 verwendet, installierte ich also das Gem mit der aktuellen 1.0 Version von Devise:

gem install devise --version 1.0.8

Als nächstes muss Devise in das Rails-Projekt eingebunden werden:

script/generate devise_install

Devise gibt daraufhin ein paar Hinweise aus, was auf jeden Fall manuell angepasst werden muss:
  • Der ActionMailer braucht default_url_options, um die Bestätigungsmais korrekt erzeugen zu können

  • Es muss einen root-Controller geben

  • Im (default-) Layout müssen die Flashes für :notice und :alert vorhanden sein

Damit kann das erste Model für unser Login generiert werden:

thomas$ script/generate devise User
exists app/models/
create app/models/user.rb
exists db/migrate
create db/migrate/20100925163708_devise_create_users.rb
route map.devise_for :users


In der erzeugten Migration und in der User-Klasse kann man nun erst mal die verschiedenen Module aktivieren bzw. deaktivieren und kann dabei auch noch weitere Attribute für das User-Model aufnehmen. Anschließend muss man natürlich die Datenbank per rake db:migrate aktualisieren.

In der User-Klasse sehen die Devise-Module dann so aus:

# Include default devise modules. Others available are:
# :http_authenticatable, :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :activatable
devise :registerable, :database_authenticatable, :recoverable,
:rememberable, :trackable, :validatable


Nun noch in den ApplicationController die Zeile

before_filter :authenticate_user!

einfügen, und schon bekomme ich eine Login-Seite mit der Möglichkeit der Neu-Registrierung und der Zusendung eines vergessenen Passworts an die Mail-Adresse (die im übrigen der default-Login ist).

Die verwendeten Views kommen direkt aus dem gem. Um sie anzupassen, kann man sie ganz einfach in die eigene Anwendung kopieren:

thomas$ script/generate devise_views
exists app/views
create app/views/confirmations
create app/views/confirmations/new.html.erb
create app/views/devise_mailer
create app/views/devise_mailer/confirmation_instructions.html.erb
exists app/views/devise_mailer
create app/views/devise_mailer/reset_password_instructions.html.erb
exists app/views/devise_mailer
create app/views/devise_mailer/unlock_instructions.html.erb
create app/views/passwords
create app/views/passwords/edit.html.erb
exists app/views/passwords
create app/views/passwords/new.html.erb
create app/views/registrations
create app/views/registrations/edit.html.erb
exists app/views/registrations
create app/views/registrations/new.html.erb
create app/views/sessions
create app/views/sessions/new.html.erb
exists app/views/shared
create app/views/shared/_devise_links.erb
create app/views/unlocks
create app/views/unlocks/new.html.erb


Nach dem Einfügen von ein paar CSS-Anweisungen sieht meine Benutzeranmeldung nun schon sehr professionell aus!

Als nächstes will ich ein zweites Model für die Administratoren einführen. Doch das kommt in einem neuen Post....