Section 13.5.3 : Authentification avec Devise et autorisation Pundit
🎯 Objectif pédagogique
Implémenter un système d'authentification complet avec Devise (inscription, connexion, mot de passe oublié) et gérer les autorisations avec Pundit (qui peut faire quoi).
Devise : l'authentification en 10 minutes
Devise est LA gem d'authentification de Rails. Elle gère inscription, connexion, déconnexion, récupération de mot de passe, confirmation email, et bien plus.
# Installation
bundle add devise
rails generate devise:install
rails generate devise User
rails db:migrate
Cela crée automatiquement :
- →Le modèle
Useravec email et mot de passe chiffré - →Les routes de connexion/inscription
- →Les vues de formulaire
- →Les migrations de base de données
Configuration Devise
# app/models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:confirmable, :trackable
has_many :articles
has_one :profile
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :authenticate_user! # Requiert connexion partout
# Permettre des champs supplémentaires à l inscription
before_action :configure_permitted_parameters, if: :devise_controller?
private
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :avatar])
devise_parameter_sanitizer.permit(:account_update, keys: [:name, :avatar])
end
end
Helpers Devise dans les vues
<% if user_signed_in? %>
<span>Bonjour, <%= current_user.name %></span>
<%= link_to 'Mon profil', edit_user_registration_path %>
<%= button_to 'Déconnexion', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'Connexion', new_user_session_path %>
<%= link_to 'Inscription', new_user_registration_path %>
<% end %>
Pundit : l'autorisation
L'authentification répond à "Qui êtes-vous ?". L'autorisation répond à "Que pouvez-vous faire ?". Pundit gère cette seconde question.
bundle add pundit
rails generate pundit:install
# app/policies/article_policy.rb
class ArticlePolicy < ApplicationPolicy
def index?
true # Tout le monde peut voir la liste
end
def show?
true # Tout le monde peut voir un article
end
def create?
user.present? # Tout utilisateur connecté
end
def update?
user == record.author || user.admin?
end
def destroy?
user == record.author || user.admin?
end
class Scope < Scope
def resolve
if user&.admin?
scope.all
else
scope.where(published: true)
end
end
end
end
# Dans le controller
class ArticlesController < ApplicationController
def show
@article = Article.find(params[:id])
authorize @article # Vérifie ArticlePolicy#show?
end
def index
@articles = policy_scope(Article) # Filtre via Scope
end
end
Authentification vs Autorisation
← Scroll horizontally →
Un utilisateur est connecté mais essaie de supprimer un article qui ne lui appartient pas. Quelle erreur est levée ?
Apprendre l’IA, du premier prompt aux agents