Les Crash-Devs d'un Passionné

Créer une authentification sur le système interne de django

/Catégorie/django

Temps de lecture : 4 minutes

Django embarque un système d'authentification et nous allons voir comment se reposer sur ce système.

1) Création du routage

Il faut éditer le fichier urls.py de votre application pour indiquer à Django de suivre :

  • tous les liens vers le sytème d'authentification propre à django pour demander une authentification sur les urls
  • le lien /login vers le sytème d'authentification propre à django pour la connexion
  • le lien /logout vers le sytème d'authentification propre à django pour la déconnexion
  • le lien /join vers la vérification du formulaire après une demande d'inscription
  • le lien /dashboard vers la vue une fois que l'authentification a réussi

L'ordre de routage est executé dans l'ordre de déclaration.

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from django.conf.urls.defaults import *
from django.contrib.auth.decorators import login_required
from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
        (r'^$' , login_required(direct_to_template, redirect_field_name=''),{'template':'registration/login.html' }),
        (r'^login$', 'django.contrib.auth.views.login'),
        (r'^logout$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
        (r'^join$', 'engine.views.join'),
        (r'^dashboard$', 'engine.views.dashboard'),
 )

Le template de connexion par défaut est stocké dans registration/login.html, mais vous pouvez spécifier un autre fichier. Je redéfini le redirect_field_name car par défaut dans l'url un paramètre GET next est inséré. Dans ma définition je ne place pas de paramètre GET.

Pour la déconnexion, je spécifie une redirection vers / après cette déconnexion.

Il faut aussi définir des variables dans le fichiers settings.py, elles sont nécessaire pour login_required()

LOGIN_URL = '/login' # Lien vers la page si l'authentification échoue 

LOGIN_REDIRECT_URL = '/dashboard' # Lien vers la page si l'authentification réussi

Par défaut le LOGIN_URL pointe sur le lien /accounts/login

Voilà un exemple du template de registration/login.html

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
        <p>La connexion a échoué...</p>
{% endif %}
        <form method="post" action="{% url django.contrib.auth.views.login %}">
        {% csrf_token %}
        <table>
                <tr>
                         <td>{{ form.username.label_tag }}</td>
                         <td>{{ form.username }}</td>
                </tr>
                <tr>
                         <td>{{ form.password.label_tag }}</td>
                         <td>{{ form.password }}</td>
                </tr>
        </table>
        <input type="submit" value="login" />
        <input type="hidden" name="next" value="{{ next }}" />
        </form>
{% endblock %}

Nous venons de créer le système d'authentification, maintenant nous allons voir comment créer le système de création d'un utilisateur

2) Création d'un utilisateur

Django possède son propre système de gestion des utilisateurs, notamment utilisé pour la connexion sur la partie admin de Django.

Nous allons étendre cette fonctionnalité pour ajouter d'autres informations sur cet utilisateur (pour l'exemple cela correspond à l'id_version

Cela se nomme un profile sous django. Nous allons définir le nom de notre profile dans settings.py dans notre application (ici core)

AUTH_PROFILE_MODULE = 'core.CustomerProfile'

Puis le modèle de ce profile dans models/customerprofile.py

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from django import forms
from django.db import models
from django.contrib.auth.models import User
class CustomerProfile(models.Model):
    id_customerprofile = models.AutoField(primary_key = True)
    user = models.ForeignKey(User, unique=True)
    surname = models.CharField(max_length=50)
    firstname = models.CharField(max_length=50)
    email = models.EmailField()
    password = forms.CharField(max_length=15, widget=forms.PasswordInput)
    id_version = models.IntegerField(default=1)

    class Meta:
        app_label='core'

On remarque que ce profile possède un lien vers une clé étrangère qui pointe sur la table auth_user

Il faut penser à ajouter le lien dans __init__.py dans votre model

from customerprofile import *

Je personnalise le formulaire car je ne veux pas afficher le champ de la Foreing Key. Je veux que l'utilisateur remplisse uniquement son nom, prénom, email et mot de passe.

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{% extends "base.html" %}
{% block content %}
<form action="#" method="post" class="form-analyzer center">
{% csrf_token %}
<div class="fieldWrapper">
{{ formcustomer.surname.errors }} Nom: {{ formcustomer.surname }}</div>
<div class="fieldWrapper"><span class="Apple-tab-span" style="white-space:pre"> 
{{ formcustomer.firstname.errors }} Prénom: {{ formcustomer.firstname }}</div>
<div class="fieldWrapper">
{{ formcustomer.email.errors }} Email: {{ formcustomer.email }}</div>
<div class="fieldWrapper"><span class="Apple-tab-span" style="white-space:pre"> 
{{ formcustomer.password.errors }} Mot de passe: {{ formcustomer.password }}</div>
 <input type="submit" value="Submit" />
</form>

{% endblock %}

Et le fonctionnement dans la view.py

clipboard
Copier le code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class CustomerProfileForm(forms.ModelForm):
    id_customerprofile = models.AutoField(primary_key = True)
    user = models.ForeignKey(User, unique=True)
    surname = forms.CharField(max_length=50)
    firstname = forms.CharField(max_length=50)
    email = forms.EmailField()
    password = forms.CharField(max_length=15, widget=forms.PasswordInput)
    id_version = models.IntegerField(default=1) # Champ forcé à 1

    class Meta:
        model = CustomerProfile
        app_label = 'core'

def join(request):
    if request.method == 'POST':
        # Création du user de base
        userDjango = User.objects.create(username=request.POST['surname'], last_name=request.POST['surname'], first_name=request.POST['firstname'], email=request.POST['email'])

        userDjango.set_password(request.POST['password'])
        userDjango.save()
        # Ajpout d'information dans le profile, on aurait pu aussi simplement ajouter l'id_version
        form = CustomerProfile()
        form.surname=request.POST['surname']
        form.firstname=request.POST['firstname']
        form.email=request.POST['email']
        form.user=userDjango
        form.save()
    else:
        form = CustomerProfileForm()
    return render_to_response('registration/createcustomer.html', {'formcustomer' : form}, context_instance=RequestContext(request))