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

Interceptadores

Prezados, boa noite,

preciso de ajuda por gentileza.

Quando clico em Entrar na página de login nada acontece. Já consultei no MongoDB e o usuário e senha estão corretos. Nada aparece no console. No CMD aparece

Nenhum token enviado

Parece que a aplicação quer um token, logo na tela de login, na $window.sessionStorage. Entendi que a configuração no Consign evitaria isso.

Como estão os arquivos:

express.js:

var express = require('express');
var consign = require('consign');
var bodyParser = require('body-parser');

var app = express();

app.use(express.static('./public'));

app.use(bodyParser.json());

app.set('secret', 'GALOFORTEVINGADOR');

consign({cwd: 'app'})
    .include('models')
    .then('api')
    .then('routes/auth.js')
    .then('routes')
    .into(app);

module.exports = app;

app/api/auth.js:

var mongoose = require('mongoose');

module.exports = function(app) {
    var api = {};
    var model = mongoose.model('Usuario');

    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álido(s)');
                res.sendStatus(401);
            } else {
                var token = jwt.sign(
                    {login: usuario.login}, 
                    app.get('secret'), 
                    {expiresIn: 900} // valor em segundo, aqui temos um total de 15 minutos
            );
            console.log('Autenticado: token adicionado na resposta');
            res.set('x-access-token', token); // adicionando token no cabeçalho de resposta
            res.end();
            }
        });
    };
    api.verificaToken = function(req, res, next) {
        var token = req.headers['x-access-token']; // busca o token no header da requisição
        if (token) {
            console.log('Iniciando decodificação do token');
            jwt.verify(token, app.get('secret'), function(err, decoded) {
                if (err) {
                    console.log('Token rejeitado');
                    return res.destStatus(401);
                }
                else {
                    console.log('Token aceito')
                    req.usuario = decoded;
                    next();
                }
            });
        }
        else {
            console.log('Nenhum token enviado');
            return res.sendStatus(401);
        }
    };
    return api;
};

app/routes/auth.js:

module.exports = function(app) {
    var api = app.api.auth;
    app.post('/autenticar', api.autentica);
    app.use('/*', api.verificaToken);
};

login.html:

<h1 class="text-center">Login</h1>

<p class="alert-danger">{{mensagem}}</p>
<form ng-submit="autenticar()">
    <div class="form-group">
        <label>Código do Usuário</label>
        <input type="text" ng-model="usuario.login" class="form-control">
    </div>
    <div class="form-group">
        <label>Senha</label>
        <input type="password" ng-model="usuario.senha" class="form-control">
    </div>
    <input type="submit" value="Entrar" class="btn btn-primary">
</form>

Obrigado pelo apoio.

8 respostas

Depois de uns 5 minutos aparece mensagem de erro no console:

POST http://localhost:3000/autenticar net::ERR_EMPTY_RESPONSE

Código do main.js e do interceptador. No aguardo.

Professor,

obrigado.

Seguem abaixo:

main.js

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

    $httpProvider.interceptors.push('tokenInterceptor');

    $locationProvider.html5Mode(true);

    $routeProvider.when('/fotos', {
        templateUrl: 'partials/principal.html',
        controller: 'FotosController'
    });

    $routeProvider.when('/fotos/new', {
        templateUrl: 'partials/foto.html',
        controller: 'FotoController'
    });

    $routeProvider.when('/fotos/edit/:fotoId', {
        templateUrl: 'partials/foto.html',
        controller: 'FotoController'
    });    

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

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

});

Interceptador

angular.module('alurapic')
    .factory('tokenInterceptor', function($q, $window, $location) {
        var interceptor = {};

        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');
            if (token != null) {
                $window.sessionStorage.token = token;
                console.log('Token na sessionStorage é ', token);
            }
            return response;
        },

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


    return interceptor;    
});

Poste o seu controller que sua tela de login chama.

Olha o seu api.autentica, você colocou código fora do else do IF. Dá uma verificada..

solução!

Professor,

não encontrei código fora do else.

Verifiquei o código e descobri que consegui a proeza de não importar o JWT:

var jwt  = require('jsonwebtoken');

Apenas isto foi suficiente para o CRUD executar totalmente.

De qualquer forma, seguem os códigos para caso queira fazer mais alguma crítica.

login-controller:

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

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

    $scope.autenticar = function() {
        var usuario = $scope.usuario;

        $http.post('/autenticar', {login: usuario.login, senha: usuario.senha})
        .then(function(){
            $location.path('/');
        }, function(erro) {
            $scope.usuario = {};
            $scope.mensagem = 'Código do usuário ou senha incorreto(s)';
        });
    };

});

Desde já agradeço.

Tem razão, eu que me enganei ao ver um parênteses como chave! :) To ficando velho!

Foi a ausência do jwt? Que bom que descobriu, aliás, como você não havia importado pensei que o console do servidor fosse reclamar dizendo que você esta usando algo que não existe.

O resto está OK. Nem passou pela minha cabeça que o problema pudesse ser ausência de importação de um módulo, até porque o servidor já gritaria exibindo mensagens de erro, não apenas a que você postou no início.

Mas tá tudo certo agora? Se chegou até aqui, é porque esta no final do curso. Espero que tenha gostado e tenha ficado mais confiante nessa tecnologia, construindo manualmente a MEAN Stack.

Sucesso e bom estudo José!