Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Sobre JWT

Galera, eu tenho uma dúvida!

Seguindo as aulas corretamente minha plataforma está funcionando com a autenticação porJWT corretamente.

Mas eu queria adicionar mais duas funções que seria o botão Sair (deleta o token criado no header e volta para a página de login) e queria também exibir o usuário já logado (conforme o login salvo no JWT).

Eu notei que no final da explicação sobre JWT o Fábio colocou uma linha dizendo como eu consigo excluir o token, mas não consegui implementa-lo.

E também não consigo pegar o login que foi realizado, sei que ele é armazenado no JWT, mas não sei se seria correto buscar diretamente de lá essa informação.

Poderiam me dar um help ? Agradeço !

8 respostas

Ah, uma solução rápida é não alterar nada no Server. No controller. ..vc usa o login do campo. Se foi efetuado é porque ele existe. Guarde o login no $rootScope. Isso é killer...resolve sem alterar uma vírgula no Server. O que estiver em rootScope e acessado por todas as views e controller. Existem zilhoes de formas.

Para excluir o token é só olhar para o código do interceptador. Onde você grava o token? Então, no seu controller você acessa o mesmo lugar apagando-o.

Aliás, meu nome é Flávio Almeida, não Fábio :)

Escreve seu código aqui.

.

Flavio me desculpe por errar seu nome rs.

Coloquei a seguinte função no controller Login para apagar a sessão, funcionou corretamente da forma desejada:

$scope.sair = function(){                    
        delete $window.sessionStorage.token;
        $location.path('/');
        console.log('Token Retirado');
    };

Sobre usar a $rootScope eu não entendi a hora que eu devo alimentar a variável com o usuário logado.

Obrigado pela ajuda!

Oi Alan! Excelente, era isso mesmo que eu tinha em mente.

Agora, sobre exibir a informação de login, a solução mais rápida e fácil é alterar login-controller. Altere $scope.autenticar. Veja que o método, quando o login é efetuado com sucesso, realiza um location.path('/'). Antes dessa instrução, pegue $scope.usuario.login que tem o nome do usuário que você entrou no formulário (se o login é válido, o login entrada é o mesmo que esta lá no servidor, por isso não precisamos alterar o servidor para que envie essa informação). e grave em $rootScope.login. Lembre-se que você precisa recebe $rootScope por injeção no controller. Como a informação está em $rootScope, você pode acessá-la em index.html , antes da tag <ng-view></ng-view> como:

<!-- colocar em index.html, antes de <ng-view></ng-view>
<p ng-if="login" >Usuario logado: {{login}}</p>

Um dado no $rootScope é acessível em qualquer lugar da nossa aplicação.

Segue o código alterado de LoginController. Existem zilhões de formas de se fazer o que você quer, essa é uma solução que você pode melhorar:

angular.module('alurapic').controller('LoginController', function($scope, $http, $location, $rootScope) {

    $scope.usuario = {};
    $scope.mensagem = '';

    $scope.autenticar = function() {

        var usuario = $scope.usuario;

        $http.post('/autenticar', {login: usuario.login, senha: usuario.senha})
        .then(function() {
            $rootScope.login = $scope.usuario.login
            $location.path('/');
        }, function(erro) {
            $scope.usuario = {};
            $scope.mensagem = 'Login/Senha incorretos';
        });
    };
});

Flávio, funcionou da forma como você me passou, ao fazer o login o nome do usuário logado traz corretamente.

Só notei uma observação, quando eu atualizo com F5 a página atual, o nome some, como se a variável estivesse sendo esvaziada.

Sim, ela está sendo esvaziada. Uma SPA é uma página que não recarrega durante seu uso. Os dados só ficam lá porque o usuário não recarrega a página. Se ele vai e aperta F5 ele está iniciando a aplicação do zero. Daí você perde a informação.

Se você quiser manter o nome do usuário disponível mesmo quando ele tecle ENTER, grave o usuário no $window.sessionStorage. Veja que é a mesma lógica do token. Você precisará criar um tal de UsuarioLogadoController que vai acessar o sessionStorate e disponibilizar o usuário logado. Use ng-controller no parágrafo. Há zilhões de formas de fazer, essa é mais uma. Aliás, já pesquisou na internet? Cada uma tem vantagem e desvantagem.

Só não esqueça de no "sair" limpar o nome do usuário, assim como você faz com o token.

solução!

Oi Alan, vou te passar mais uma solução aqui, mas você lapida depois, tudo bem?

Veja que no LoginController eu guardo o usuário no $rootScope e também no sessionStorage:

angular.module('alurapic').controller('LoginController', function($scope, $http, $location, $rootScope, $window) {

    $scope.usuario = {};
    $scope.mensagem = '';

    $scope.autenticar = function() {

        var usuario = $scope.usuario;

        $http.post('/autenticar', {login: usuario.login, senha: usuario.senha})
        .then(function() {

            $window.sessionStorage.login = $scope.usuario.login;
            $rootScope.login = $scope.usuario.login;

            $location.path('/');

        }, function(erro) {
            $scope.usuario = {};
            $scope.mensagem = 'Login/Senha incorretos';
        });
    };

});

Perfeito, agora em index.html, antes de <ng-view></ng-view> temos:

<p>Usuario logado: {{login}}</p>

Para revolver o problema do usuário recarregar a página com o F5 vamos fazer com que assim que a página seja recarregada ele pegue o usuário do sessionStorage jogando-o novamente para o $rootScope:

angular.module('alurapic', ['minhasDiretivas','ngAnimate', 'ngRoute', 'ngResource', 'meusServicos'])
    .config(function($routeProvider, $locationProvider, $httpProvider) {

        // rotas da sua aplicação.

    })
    .run(function($rootScope, $window) {
        $rootScope.login = $window.sessionStorage.login;
    });

Veja que usei a função run executada assim que nossa aplicação é carregada.

Bom, acho que com isso você tem material bem legal para lapidar e resolver esse problema. Só não esqueça de limpar o token e o login quando fizer logout do sistema.