Laravel

Un framework qui rend heureux

Voir cette catégorie
Vers le bas
Laravel et AngularJS : login et logout
Dimanche 12 avril 2015 16:18

Dans cet article de la série on va voir comment s'effectue le login et par la même occasion le logout. On va voir comment sont gérées les erreurs de saisie à l'issue de la validation et comment AngularJS adapte l'interface selon le statut de l'utilisateur.

Nota : cet article est le troisième de la série, le premier se trouve ici.

Le login

La soumission du formulaire

On a vu qu'il est prévu une option LOGIN dans le menu :

img95 Avec ce code :
<li ng-hide="isLogged">
    <a class="page-scroll" href="#auth">Login</a>
</li>
On référence une ancre dans la page et on se retrouve avec le formulaire : img78 La soumission est prise en charge par AngularJS avec le contrôleur LoginCtrl et la directive ng-submit :
<form ng-controller="LoginCtrl" ng-submit="submit()" accept-charset="UTF-8" role="form">
A la soumission on appelle la méthode submit du contrôleur LoginCtrl :
dreamsControllers.controller('LoginCtrl', ['$scope', 'Login',
    function LoginCtrl($scope, Login) {
        $scope.isAlert = false;

        /* Login */
        $scope.submit = function () {
            $scope.errorEmail = null;
            $scope.errorPassword = null;
            $scope.isAlert = false;
            Login.save({}, $scope.formData,
                function success(response) {
                    if (response.result === 'success') {
                        $scope.$parent.isLogged = true;
                        $scope.$parent.paginate();
                        window.location = '#page-top';
                    } else {
                        $scope.isAlert = true;
                    }
                },
                function error(errorResponse) {
                    if (errorResponse.data.password) {
                        $scope.errorPassword = errorResponse.data.password[0];
                    }
                    if (errorResponse.data.email) {
                        $scope.errorEmail = errorResponse.data.email[0];
                    }
                }
            );
        };

    }]);
On voit qu'on injecte le service Login que voici :
dreamsServices.factory('Login', ['$resource',
    function ($resource) {
        return $resource("login", {}, {
            save: {method: 'POST'}
        });
    }]);
On envoie donc une requête de type POST à Laravel sur la route login. On se retrouve dans le contrôleur AuthController :
/**
 * Send the response after the user was authenticated.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  User $user
 * @return \Illuminate\Http\Response
 */
public function authenticated(Request $request, User $user)
{
    return response()->json(['result' => 'success']);
}

/**
 * Get the failed login response instance.
 *
 * @param \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
protected function sendFailedLoginResponse(Request $request)
{
    return response()->json(['result' => 'fail']);
}
L'essentile du code se trouve dans le trait AuthenticatesUsers.

La validation

On a une première étape de validation. Si elle échoue Laravel renvoie une réponse JSON avec un code 422, par exemple :
{"email":["The email must be a valid email address."]}
Dans le contrôleur de AngularJS on a ce code :
function error(errorResponse) {
    if (errorResponse.data.password) {
        $scope.errorPassword = errorResponse.data.password[0];
    }
    if (errorResponse.data.email) {
        $scope.errorEmail = errorResponse.data.email[0];
    }
}

On transmet donc l'erreur dans des variables du scope. On va donc permettre l'affichage dans le formulaire, par exemple au niveau de l'email :

<div class="form-group col-lg-6" ng-class="{'has-error': errorEmail}">
    <input ng-model="formData.email" class="form-control" placeholder="email" name="email" type="email" id="email" required>
    <small class="help-block">{{ errorEmail}}</small>
</div>
Avec cet aspect : img79

Si la validation réussit mais que les informations fournies ne correspondent à aucun utilisateur mémorisé dans la table on n'est plus en situation de réponse avec erreur mais avec le JSON et le code 200 :

{"result":"fail"}

Dans le contrôleur de AngularJS on a :

function success(response) {
    if (response.result === 'success') {
        ...
    } else {
        $scope.isAlert = true;
    }
},

On met donc la valeur true dans la variable isAlert. Ce qui a pour effet d'afficher la barre d'alerte avec la directive ng-show  :

<div ng-show="isAlert" class="alert alert-danger" role="alert">
    These credentials do not match our records.
</div>

Et cet aspect :

img80

Connexion réussie

Si la connexion réussit c'est cette partie du code du contrôleur de AngularJS qui est activée :
function success(response) {
    if (response.result === 'success') {
        $scope.$parent.isLogged = true;
        $scope.$parent.paginate();
        window.location = '#page-top';
    } else {
        ...
    }
},
On va alors procéder à 3 actions :
  • mettre la variable isLogged à true (en remontant dans le scope parent) pour avoir l'adaptation de l'interface
  • appeler à nouveau la page actuelle des rêves pour connaître ceux qui appartiennent à l'utilisateur connecté et mettre ainsi à jour les icônes de modification des rêves avec la méthode paginate
  • remonter en haut de la page
On se retrouve alors avec le menu adapté : img96 Le formulaire de bas de page s'est aussi transformé pour pouvoir ajouter un rêve :

img85

Le logout

Le logout s'effectue en utilisant l'option LOGOUT du menu. On trouve ce code dans la page :
<li ng-show="isLogged">
    <a ng-click="logout()" href>Logout</a>
</li>
On voit qu'un clic appelle la méthode logout du contrôleur de AngularJS :
/* Logout */
$scope.logout = function () {
    Logout.get({},
        function success() {
            $scope.isLogged = false;
            $.each($scope.data, function(key) {
                $scope.data[key].is_owner = false;
            });
        },
        function error(errorResponse) {
            console.log("Error:" + JSON.stringify(errorResponse));
        }
    );
};
On appelle la méthode get du service Logout :
dreamsServices.factory('Logout', ['$resource',
    function ($resource) {
        return $resource("logout", {}, {
            get: {method: 'GET'}
        });
    }]);
On envoie donc une requête de type GET à Laravel sur la route logout. On se retrouve avec la méthode surchargée logout dans le contrôleur AuthController :
/**
 * Log the user out of the application.
 *
 * @return \Illuminate\Http\Response
 */
public function logout()
{
    $this->auth->logout();

    return response()->json(['result' => 'success']);
}
L'utilisateur est déconnecté et on renvoie un simple réponse JSON. Côté AngularJS on procède alors à 2 actions dans le contrôleur :
  • mettre la variable isLogged à false pour avoir l'adaptation de l'interface
  • mettre à false toutes les propriétés is_owner pour rafraichir les icônes de modification des rêves
Le menu se retrouve ainsi : img95 Et le formulaire redevient celui du login : img78

Les autres actions

Les autres actions au niveau de l'utilisateur ne sont pas gérées par AngularJS.

L'enregistrement

Dans le formulaire de login on a un bouton I WANT TO SUSCRIBE ! Ce bouton référence directement la route de Laravel :
<a href="auth/register" class="btn btn-default">I want to suscribe !</a>
C'est la méthode getRegister du trait RegistersUsers qui est sollicitée. Le contrôleur renvoie alors la vue : img86 La soumission se fait sur la méthode postRegister du trait. Pour avoir une redirection correcte il faut surcharger la propriété $redirectTo dans le contrôleur AuthController :
/**
 * Where to redirect users after login / registration.
 *
 * @var string
 */
protected $redirectTo = '/';

Le renouvellement du mot de passe

De la même façon le renouvellement du mot de passe se fait de façon classique avec juste les vues adaptées à l'esthétique du site. Par exemple voilà le formulaire pour saisir son email :

img99 Je n'insiste pas sur cette partie classique de Laravel. Dans le prochain article nous verrons la gestion des rêves.


Par bestmomo

Nombre de commentaires : 2