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

Carregar dados do usuário logado

Como eu poderia fazer para pegar os dados do usuário que esta na sessão? Exibir o nome do usuário logado por exemplo?

Olhando o findOne da api/auth, ele recupera o usuário de acordo com login e senha, então acredito que não sirva como base. Poderia pegar o usuário pelo Token?

13 respostas

Quando você efetua o login, você recebe o usuário, um objeto. Você precisará guardá-lo no localStorage assim como fez no token para poder referenciá-lo onde desejar. Lembre-se que você só terá uma chance para armazená-lo, ou seja, assim que efetuar o login.

Ah, em Single Page Application não existe sessão, só lembrando! Quem guarda informações que seriam equivalente a sessão é seu browser. Eu sei , seu sei, algo completamente diferente de uma aplicação web tradicional.

Eu dei uma olhada no autenticar e fiz o seguinte:

api.autentica = function(req, res) {

         model.findOne({
             login: req.body.login,
             senha: req.body.senha
         })
         .then(function(usuario) {
             if (!usuario) {
                 console.log('Login/senha inválidos');
                 res.sendStatus(401);
             } else {
                console.log(usuario.login)
                 var token = jwt.sign({login: usuario.login}, app.get('secret'), {
                     expiresIn: 84600
                 });
                var usuario = usuario;
                 console.log('Autenticado: token adicionado na resposta');
                 res.set('x-access-token', token, usuario);
                 res.end(); 
             }
         });
     };

O que voce acha?

Alias, apos fazer o clicar no botão de "Login" como eu configuro para qual a pagina ele via? Poderia fazer isso?

Hoje, você tem uma tela de login no seu sistema. Certo? Quando você efetua o login, você não recebe o token? Mas além do token receberá o usuário via res.json. Você não vai colocar o usuário no header http. Troque res.end por res.json(usuario). E lá no seu Angular, recebe o retorno e guarda esse usuário.

Até agora eu fiz o seguinte:

 interceptor.request = function(config) {
            // enviar o token na requisição
            config.headers = config.headers || {};
            if ($window.sessionStorage.token) {
                console.log('Enviando token já obtido em cada requisição');
                config.headers['x-access-token'] = $window.sessionStorage.token;
            }
            return config;
        },

        interceptor.response = function (response) {
            var token = response.headers('x-access-token');
            var usuario = response.json(usuario);
            if (token != null) {
                $window.sessionStorage.token = token;
                $window.sessionStorage.usuario = usuario;
                console.log('Token no session storage: ', token);
            } 
            return response;
        },

        interceptor.responseError = function(rejection) {

            if (rejection != null && rejection.status === 401) {
                console.log('Removendo token da sessão')
                delete $window.sessionStorage.token;
                delete $window.sessionStorage.usuario;
                $location.path("/login");
            } 
            return $q.reject(rejection);
        }

Ainda estou com duvida no interceptor.request, como eu faria?

Descreva o fluxo passo a passo para mim do que você acha que deve acontecer. Isso lhe ajudará a fazer as perguntas certas. Inclusive, evitará tentativa e erro.

No atutentica eu vou devolver o usuario em json:

api.autentica = function(req, res) {

         model.findOne({
             login: req.body.login,
             senha: req.body.senha
         })
         .then(function(usuario) {
             if (!usuario) {
                 console.log('Login/senha inválidos');
                 res.sendStatus(401);
             } else {
                console.log(usuario.login)
                 var token = jwt.sign({login: usuario.login}, app.get('secret'), {
                     expiresIn: 84600
                 });
                var usuario = usuario;
                 console.log('Autenticado: token adicionado na resposta');
                 res.set('x-access-token', token);
                 res.json(usuario);
             }
         });
     };

La no angular eu tenho que pegar esse json e enviar a cada nova requisição que foi feita. O token foi enviado usando res.set, mas o usuario foi enviado com res.json, então eu não tenho onde me basear para dar continuidade.

O fluxo não é esse.

Seu token pode guardar qualquer coisa dentro dele no payload, certo? O que você guarda hoje lá? Se não me engano, é o nome do usuário. Mas a aplicação Angular não consegue descriptografar o token. Perfeito? Então, para exibir o nome do usuário em sua aplicação, você precisa guardar o nome do usuário ou o objeto usuário assim que se logar. Certo?

No envio para o servidor, não muda nada. Você só envia o token. La no servidor você descriptografa o token como já faz. Se lá dentro desse token, você colocou alguma informação de permissão do usuário, poderá acessa-la e decidir se bloqueia ou não acesso a determinado recurso. Só isso.

No lado do angular você só guarda o usuário poara poder aplicar alguma lógica sobre ele.

Existem diversas formas de se fazer isso, tente achar a que faça mais sentido para você.

Talvez esse vídeo possa complementar seu entendimento.

https://thinkster.io/tutorials/angularjs-jwt-auth

Lembrando que autenticação em SPA não tem nada a ver com autenticação baseada em sessão no lado do servidor, não existe session. Por isso sua APP angular tem que guardar o estado da aplicação. É esse o pulo do gato que você tem que ter sempre em mente.

Aliás, o problema que você esta tentando resolver é interessante, porque depois que você encaixar cada peça, é a mesma coisa com qualquer outra linguagem.

solução!

Na verdade isso não deveria nem ser um problema, ja que eu estou passando o usuario.login quando crio o Token. Eu deveria conseguir recuperar isso facilmente depois.

var token = jwt.sign({login: usuario.login}, app.get('secret'), {
                     expiresIn: 84600
                 });

Ficar enviando o json do usuário a cada requisição como você sugeriu no começo não me parece fazer sentido, eu não vou usar ele em todas as paginas.

Eu preciso extrair o usuário a partir do token nas paginas que eu for utilizar alguma informação do usuario.

https://auth0.com/docs/api/authentication#get-user-info

Poderia criar uma função que tem como parametro o token e retiro o usuario dela.

Mas como estou começando agora, não posso ficar na tentativa e erro como voce comentou.

Acredito que vou ter que trocar toda a implementação de autorização que foi usada no curso para outra.

Não faz sentido no interceptor. Ta tudo no caminho. A unica coisa que você precisa reenviar é o token e não o usuario que recebeu. O usuario vc recebe no login e guarda. Servidor não o envia mais.Esse usuario pode ser objeto cheio de propriedades e não uma string apenas.

Vc precisa dele para o angular ocultar coisas de acordo com perfil. O mesmo dado esta no token e e usado no server para saber se o usuario pode ou não acessar api.

Pegou a ideia?

Recebe o usuário e coloca no $rootScope. Dai você acessa via AE o dado do usuário de onde quiser.