Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
10
respostas

Unauthorized quando tento acessar a minha tela de login

O Código está correto mas, quando tento acessar minha tela de login, a página me exibe "Unauthorized" e recebo "401" no console do navegador.

module.exports = function(app){

    var mongoose = require('mongoose');
    var jwt = require('jsonwebtoken');    

    var api = {};
    var model = mongoose.model('Usuario');

    api.autentica = function (request,response){

        model.findOne({
            id: request.body.login,
            senha: request.body.senha
        })

        .then(function(usuario){
            if(!usuario){
                console.log('Login/senha inválidos');
                response.sendStatus(401);
            }else{
                console.log(usuario.login);
                var token = jwt.sign({id: usuario.login}, app.get('secret'),{
                    expiresIn: 120
                });

                console.log('Autenticando: token adicionando na resposta');
                response.set('x-access-token', token);
                response.end();
            }
        },function(error){
            console.log(error);
            response.sendStatus(401);
        });
    };

    api.verificaToken = function(request,response, next){

        var token = request.headers['x-access-token'];

        if(token) {
            console.log('Token recebido,decodificando...');
            jwt.verify(token, app.get('secret'),function(err,decoded){
                if(err){
                    console.log('Token rejeitado');
                    response.sendStatus(401);
                } 
                    console.log('Token aceito!')
                    request.usuario = decoded;
                    next();              
            });
        }else {
            console.log('Nenhum token enviado...');
             response.sendStatus(401);
        }   
    }

    return api;
};
10 respostas

Pode ficar tranquila que mais de 500 alunos passaram dessa parte sem problema algum. Descobriremos o problema.

Você só verificou no lado backend, mas o interceptador do Angular? Já verificou se esta tudo correto? Verificou se ele é chamado?

Quando você diz acessar a tela de login, qual URL você esta digitando? Criou uma rota para ela?

Outra coisa, você só pode ativar a roda segura depois da rota do login, se fizer antes, bloqueará o acesso ao login. Como você definiu suas rotas?

Essas são as minhas rotas do Angular:

insira seu código aqui
```angular.module('sun',['ngRoute'])
.config(function($routeProvider, $locationProvider, $httpProvider ){

    //AQUI FICA TODAS AS ROTAS DAS VIEWS ASSOCIADAS COM OS SEUS RESPECTIVOS CONTROLLERS

    $httpProvider.interceptors.push('tokenInterceptor');
    $locationProvider.html5Mode(true); //ativa o modo html5 que remove a # da rota definida no angular


    $routeProvider.when('/usuarios',{
        templateUrl: 'partials/usuarios.html',
        controller: 'TabelaController'
    });

    $routeProvider.when('/usuarios/new',{
        templateUrl: 'partials/cadastro-usuarios.html',
        controller: 'CadastroUsuarioController'

    });

     $routeProvider.when('/login',{
        templateUrl:'partials/login.html',
        controller: 'LoginController'
    });    



    $routeProvider.otherwise({redirectTo: '/usuarios'});


});

É o mesmo exemplo usado no curso mas, utilizei para cadastrar funcionários. E sim, digito a URL "http://localhost:3000/login".

Aqui estão as minhas rotas do backend:

module.exports = function(app){

    var api = app.api.autentica;


    app.post('/autenticar', api.autentica);
    app.use('/*', api.verificaToken);  

};

Olá, não é "http://localhost:3000/login", o correto é "http://localhost:3000/#/login". Tente dessa forma.

Eu ativei o modo do HTML5.

Não vai funcionar, porque o backend que você criou não foi criado para suportar history API. Nem todo browser suporta e até hoje o gmail e o inbox usam #.

Mas funciona para as minhas outras rotas, elas ficam sem a # . Só estou com problema na minha tela de login . Quando eu tento acessá-la , aparece a tela em branco com a mensagem "Unauthorized".

solução!

Não vai funcionar porque você esta acessando diretamente a rota de login pelo navegador digitando-a. O servidor acha que é uma requisição para localhost:3000/login. Não existe essa rota e o browser não tem como saber que é uma rota do Angular. Só se o seu server for programado para devolver para qualquer requisição que ele não esteja preparado para responder a página index.html. Além disso, você terá inconsistências se mantiver o HTML5Mode sem o seu server suportar.

Faça um teste, remova o HTML5Mode e veja o resultado.

Parece que resolveu, professor Flávio! Mas , existe algum problema da minha URL ficar assim : "http://localhost:3000/#!/login" Com um "!" ?

Tem não. Também é uma URL válida. Na verdade, o # ou #! ou !# é só para o navegador entender que não é uma requisição para o lado do servidor. Dai, o Angular tem chance de analisar a URL e buscar a View parcial no servidor usando JavaScript (ajax).