Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🔐
Intermediaire 25 min Rails

Authentification dans Rails

Pourquoi Authentification dans Rails ?

L'authentification est un élément fondamental de tout site Web ou application mobile moderne. Elle permet de gérer les utilisateurs, de protéger leurs données et d'assurer la sécurité des interactions entre l'utilisateur et le système. Dans un contexte professionnel, une authentification robuste est essentielle pour maintenir la confiance des utilisateurs dans votre application.

Un cas concret serait un site de gestion de projet où les utilisateurs doivent être en mesure de s'authentifier pour consulter leurs tâches et collaborer avec d'autres membres du projet. Sans authentification, le risque est élevé que toutes les données soient accessibles à tout le monde, ce qui entraînerait des problèmes majeurs en termes de sécurité et de confidentialité.

Prerequis

  • Connaissance avancée de Ruby on Rails
  • Familiarité avec les bases de données SQL (PostgreSQL, MySQL)
  • Connaissance des concepts de modèles, de contrôleurs et de vues
  • Compréhension des routes et des formulaires HTML
  • Installation de Ruby 3.x et Rails 7.x
  • Utilisation d'un éditeur de code comme VSCode ou Sublime Text

Concepts fondamentaux

Modèle User

Le modèle User est le cœur de l'authentification. Il doit contenir les champs nécessaires pour stocker les informations de l'utilisateur, comme son nom d'utilisateur, son mot de passe et sa confirmation.

## app/models/user.rb
class User < ApplicationRecord
  # Valide la présence du nom d'utilisateur et du mot de passe
  validates :username, presence: true, uniqueness: true
  validates :password, presence: true, length: { minimum: 6 }

  # Hashage du mot de passe avant de l'enregistrer dans la base de données
  has_secure_password
end

Contrôleur Sessions

Le contrôleur Sessions gère les actions liées à l'authentification. Il inclut des méthodes pour créer une session (login) et détruire une session (logout).

## app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
  def new
    # Affiche le formulaire de connexion
  end

  def create
    user = User.find_by(username: params[:session][:username])
    if user && user.authenticate(params[:session][:password])
      log_in user
      flash[:success] = "Connecté avec succès !"
      redirect_to root_path
    else
      flash.now[:danger] = "Nom d'utilisateur ou mot de passe incorrect."
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    flash[:success] = "Déconnecté avec succès !"
    redirect_to login_path
  end
end

Formulaires HTML

Le formulaire HTML pour l'authentification est simple et utilise la méthode POST pour envoyer les données au contrôleur.

<!-- app/views/sessions/new.html.erb -->
<h1>Connexion</h1>
<%= form_with url: login_path, method: :post do |f| %>
  <%= f.label :username %>
  <%= f.text_field :username %>

  <%= f.label :password %>
  <%= f.password_field :password %>

  <%= f.submit "Se connecter" %>
<% end %>

Middleware et Helper Methods

Rails fournit des middleware et des helper methods pour gérer les sessions. Le middleware ActionDispatch::Session::CookieStore stocke la session dans un cookie.

## config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_my_app_session'

Les helper methods logged_in?, current_user et log_in sont définis dans le fichier application_controller.rb.

## app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # Méthode pour vérifier si un utilisateur est connecté
  def logged_in?
    !current_user.nil?
  end

  # Méthode pour récupérer l'utilisateur actuellement connecté
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  # Méthode pour connecter un utilisateur
  def log_in(user)
    session[:user_id] = user.id
  end

  # Méthode pour déconnecter un utilisateur
  def log_out
    session.delete(:user_id)
    @current_user = nil
  end
end

Mise en pratique : projet fil rouge

Étape 1 : Création du modèle User

rails generate model User username:string password_digest:string
rake db:migrate

Étape 2 : Création du contrôleur Sessions

rails generate controller Sessions new create destroy

Étape 3 : Configuration des routes

Ajoutez les routes dans config/routes.rb :

Rails.application.routes.draw do
  root 'tasks#index'
  resources :tasks
  get '/login', to: 'sessions#new'
  post '/login', to: 'sessions#create'
  delete '/logout', to: 'sessions#destroy'

  resources :users, only: [:new, :create]
end

Étape 4 : Création du modèle Task

rails generate model Task title:string description:text user_id:integer completed:boolean
rake db:migrate

Étape 5 : Configuration des associations

Modifier les modèles User et Task pour ajouter des associations :

## app/models/user.rb
class User < ApplicationRecord
  has_secure_password
  has_many :tasks
end

## app/models/task.rb
class Task < ApplicationRecord
  belongs_to :user
end

Étape 6 : Création de la vue des tâches

Créez une vue index pour afficher les tâches :

<!-- app/views/tasks/index.html.erb -->
<h1>Mes Tâches</h1>
<% if logged_in? %>
  <%= link_to 'Nouvelle tâche', new_task_path %>
<% else %>
  <p>Veuillez vous connecter pour voir vos tâches.</p>
<% end %>

<ul>
  <% @tasks.each do |task| %>
    <li><%= task.title %> - <%= task.description %></li>
  <% end %>
</ul>

Étape 7 : Création de la vue des formulaires

Créez une vue new pour ajouter une nouvelle tâche :

<!-- app/views/tasks/new.html.erb -->
<h1>Nouvelle Tâche</h1>
<%= form_with model: @task do |f| %>
  <%= f.label :title %>
  <%= f.text_field :title %>

  <%= f.label :description %>
  <%= f.text_area :description %>

  <%= f.submit "Ajouter tâche" %>
<% end %>

Étape 8 : Configuration des helper methods

Modifiez application_controller.rb pour inclure les helper methods :

class ApplicationController < ActionController::Base
  before_action :require_login, except: [:new, :create]

  private

  def require_login
    unless logged_in?
      flash[:danger] = "Vous devez être connecté pour accéder à cette page."
      redirect_to login_path
    end
  end
end

Erreurs frequentes et debugging

Erreur 1 : ActiveRecord::RecordInvalid

## ❌ Mauvais
user = User.create(username: params[:session][:username], password: params[:session][:password])
rails
## ✅ Correct
if user.save
  log_in user
else
  render 'new'
end

Erreur 2 : NoMethodError: undefined method 'authenticate' for nil:NilClass

## ❌ Mauvais
user = User.find_by(username: params[:session][:username])
if user && user.authenticate(params[:session][:password])
  log_in user
else
  flash.now[:danger] = "Nom d'utilisateur ou mot de passe incorrect."
  render 'new'
end
rails
## ✅ Correct
user = User.find_by(username: params[:session][:username])
if user&.authenticate(params[:session][:password])
  log_in user
else
  flash.now[:danger] = "Nom d'utilisateur ou mot de passe incorrect."
  render 'new'
end

Erreur 3 : ActionDispatch::Cookies::CookieOverflowError

## ❌ Mauvais
user_id = session[:user_id]
session.delete(:user_id)
rails
## ✅ Correct
if user_id = session[:user_id]
  session.delete(:user_id)
end

Pour aller plus loin

  1. OAuth et Authentification sociale : Ajoutez l'authentification avec des comptes Google, Facebook ou Twitter pour permettre aux utilisateurs de s'inscrire facilement.

  2. JWT (JSON Web Tokens) : Utilisez JWT pour gérer les tokens d'authentification plutôt que des sessions cookies. Cela offre une meilleure sécurité et flexibilité.

  3. Pampered Chef : Intégrez un système de gestion de mots de passe plus sécurisé en utilisant le gem Pampered Chef.

Défi pratique

Ajoutez une fonctionnalité pour les utilisateurs de modifier leurs mots de passe. Créez un formulaire de changement de mot de passe et mettez à jour la méthode update dans le contrôleur UsersController.

<!-- app/views/users/edit.html.erb -->
<h1>Modifier mon mot de passe</h1>
<%= form_with model: current_user do |f| %>
  <%= f.label :current_password %>
  <%= f.password_field :current_password, autocomplete: "current-password" %>

  <%= f.label :new_password %>
  <%= f.password_field :password, autocomplete: "new-password" %>

  <%= f.label :new_password_confirmation %>
  <%= f.password_field :password_confirmation, autocomplete: "new-password-confirm" %>

  <%= f.submit "Mettre à jour mon mot de passe" %>
<% end %>
ruby
## app/controllers/users_controller.rb
class UsersController < ApplicationController
  def edit
    @user = current_user
  end

  def update
    @user = current_user
    if @user.update(user_params)
      flash[:success] = "Mot de passe mis à jour avec succès !"
      redirect_to root_path
    else
      render 'edit'
    end
  end

  private

  def user_params
    params.require(:user).permit(:password, :password_confirmation)
  end
end

Conclusion

Cette mise en pratique complète vous permet de comprendre la structure et les concepts essentiels de l'authentification dans Rails. En suivant ces étapes, vous devriez être capable de mettre en œuvre une authentification robuste pour n'importe quel projet Rails. N'oubliez pas de tester soigneusement votre application pour vous assurer qu'elle fonctionne comme prévu et est sécurisée contre les menaces courantes.

Besoin d'aide sur Rails ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment créer une authentification simple dans un application Rails?
Pour créer une authentification simple dans un application Rails, vous pouvez utiliser le générateur de devise en tapant `rails generate Devise:install`. Ensuite, créez un modèle d'utilisateur avec `rails generate devise User` et suivez les instructions pour terminer l'installation.
Quels sont les avantages de l'utilisation de Devise pour l'authentification?
Devise est une gem populaire pour Rails qui offre une authentification robuste avec des fonctionnalités comme la confirmation d'email, le mot de passe oublié et la gestion des comptes. Elle est personnalisable et peut être intégrée facilement à l'application.
Comment sécuriser mes routes en utilisant Devise?
Pour sécuriser vos routes avec Devise, utilisez le helper `authenticate_user!` dans votre contrôleur. Cela permet de vérifier que l'utilisateur est connecté avant d'autoriser l'accès à la route. Vous pouvez également utiliser des filtres comme `before_action :authenticate_user!` pour appliquer cette sécurité sur plusieurs actions.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.