web-dev-qa-db-fra.com

Authentification de l'utilisateur dans Django Rest Framework + Angular.js web app

Je travaille sur une webapp où les utilisateurs peuvent se connecter pour voir leur cave à vin en ligne.

J'ai le Django REST configuration des modèles, ainsi que la conception frontale dans Angular mais je ' m ayant du mal à assembler les pièces et mon principal problème concerne l'authentification des utilisateurs.

J'ai lu de nombreux articles ici et divers tutoriels, mais je n'arrive pas à trouver une méthode étape par étape pour implémenter l'authentification:

  • Quel type d'authentification doit être utilisé (jeton, session, autre?)
  • Comment l'authentification est-elle gérée côté serveur (est-ce une vue? Une méthode dans UserModel ou UserManager?)
  • J'ai un modèle d'utilisateur personnalisé (en utilisant l'e-mail comme nom d'utilisateur). Puis-je utiliser la méthode de connexion générique Django ou dois-je créer la mienne?
  • Comment le processus d'authentification est-il géré entre le serveur et le client?

D'après ce que je comprends Angular fait une demande POST sur une URL où DRF vérifie que le nom d'utilisateur et le mot de passe correspondent et renvoie un jeton ou une autre preuve d'authentification).

J'ai l'impression d'être proche mais j'ai besoin d'une vision plus générale de la façon dont cela fonctionne pour assembler les pièces.

Merci d'avance

58
bpipat

J'imagine qu'il existe de nombreuses façons de le faire, laissez-moi vous expliquer ce que je fais, j'espère que cela sera utile. Ce sera un long post. J'aimerais savoir comment les autres font cela, ou de meilleures façons de mettre en œuvre la même approche. Vous pouvez également consulter mon projet de graine sur Github, Angular-Django-Seed .

J'utilise l'authentification par jeton avec Witold Szczerba http-auth-interceptor . La beauté de son approche est que chaque fois qu'une demande est envoyée à partir de votre site sans informations d'identification appropriées, vous êtes redirigé vers l'écran de connexion, mais votre demande est mise en file d'attente pour être renvoyée une fois la connexion terminée.

Voici une directive de connexion utilisée avec le formulaire de connexion. Il publie sur le point de terminaison du jeton d'authentification de Django, définit un cookie avec le jeton de réponse, définit l'en-tête par défaut avec le jeton afin que toutes les demandes soient authentifiées et déclenche l'événement de connexion http-auth-interceptor.

.directive('login', function ($http, $cookieStore, authService) {
return {
  restrict: 'A',
  link: function (scope, elem, attrs) {

    elem.bind('submit', function () {
      var user_data = {
            "username": scope.username,
            "password": scope.password,
      };

      $http.post(constants.serverAddress + "api-token-auth", user_data, {"Authorization": ""})
          .success(function(response) {
              $cookieStore.put('djangotoken', response.token);
              $http.defaults.headers.common['Authorization'] = 'Token ' + response.token;
              authService.loginConfirmed();
          });
    });
  }
}

})

J'utilise la méthode du module .run pour définir la vérification du cookie lorsqu'un utilisateur arrive sur le site, s'il a défini le cookie, j'ai défini l'autorisation par défaut.

.run(function($rootScope) {
  $rootScope.$broadcast('event:initial-auth');
})

Voici ma directive d'intercepteur qui gère les diffusions authService. Si une connexion est requise, je cache tout et affiche le formulaire de connexion. Sinon, masquez le formulaire de connexion et affichez tout le reste.

.directive('authApplication', function ($cookieStore, $http) {
    return {
        restrict: 'A',
        link: function (scope, elem, attrs) {

          var login = elem.find('#login-holder');
          var main = elem.find('#main');

          scope.$on('event:auth-loginRequired', function () {
            main.hide();
            login.slideDown('fast');
          });

          scope.$on('event:auth-loginConfirmed', function () {
            main.show();
            login.slideUp('fast');
          });

          scope.$on('event:initial-auth', function () {
             if ($cookieStore.get('djangotoken')) {
               $http.defaults.headers.common['Authorization'] = 'Token ' + $cookieStore.get('djangotoken');
             }
             else {
               login.slideDown('fast');
               main.hide();
             }
          });
        }
     }
  })

Pour l'utiliser, tout mon HTML était essentiellement comme ça.

<body auth-application>
  <div id="login-holder">
    ... login form
  </div>

  <div id="main">
    ... ng-view, or the bulk of your html
  </div>
49
Zack Argyle

Consultez également Django-rest-auth et angular-Django-registration-auth

https://github.com/Tivix/angular-Django-registration-auth

https://github.com/Tivix/Django-rest-auth

Nous avons essayé de résoudre les choses les plus courantes Django auth/registration liées à un backend et angular dans ces deux bibliothèques).

Merci!

16
chachra