NodeJS Express路由器,在中间件和路由之间传递解码的对象? [英] NodeJS Express Router, pass decoded object between middleware and route?

查看:153
本文介绍了NodeJS Express路由器,在中间件和路由之间传递解码的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在所有请求上都使用Express中间件来解码JSON Web令牌,如果成功,请将解码后的对象附加到req变量.我认为最好只是发布我的代码,它会说明一切.基本上,在我的'/user/me/'路由中,req.decoded不应为'Undefined',因为在成功登录后解码JSON Web令牌时,我的中间件应设置该变量,但它似乎不起作用不知道为什么吗?

I am using Express middleware on all requests to decode a JSON Web Token, and if it is sucessful, attaching a decoded object to the req variable. I think it is best to just post my code and it will speak for itself. Basically req.decoded should not be 'Undefined' in my '/user/me/' route because my middleware should be setting that variable when my JSON web token is being decoded after successfully logging in, but it doesn't seem to be working and am not sure why?

api.js

var mongoose = require('mongoose'),
    userSchema = require('../models/User.js'),
    User = mongoose.model('User', userSchema),
    jwt = require('jsonwebtoken'),
    config = require('../../config.js'),
    localStorage = require('localstorage');

module.exports = function(app) {

//Check if user is logged in on every request.
app.use(function(req, res, next) {

    var authToken = localStorage.getItem('token');
    jwt.verify(authToken, config.hashKey, function(err, decoded) {
        //decoded seems to be null even after login?
        if (decoded) {
            req.decoded = decoded;
        } 
    });

    next();
});

app.post('/login', function(req, res) {

    User.findOne({ username: req.body.username, password: req.body.password }, function(err, user) {
        if (err) handleError(err);
        if (user) {
            var authToken = jwt.sign({ 
                username: user.username 
                }, config.hashKey, {
                expiresInMinutes: 1440
            });

            localStorage.setItem('token', authToken);
            res.send(user);
        } else {
            res.send('Invalid username or password');
        }
    });
});

app.get('/user/me/', function(req, res) {
    //Outputs Undefined
    console.log('req.decoded=' + req.decoded);
    res.send(req.decoded);
});

app.post('/user/create', function(req,res) {

    var newUser = new User({ username: req.body.username, password: hashedPassword });
    newUser.save(function(err) {
        if (!err) {
            res.send('User created');
        } else {
            res.send(err);
        };
    });
});

};

server.js

var express = require('express'),
    path = require('path'),
    mongoose = require('mongoose'),
    bodyParser = require('body-parser'),
    require('./app/routes/api.js')(app);

mongoose.connect('localhost', 'triviaattack');

var app = express();

app.use(bodyParser.urlencoded({ extended: false }));

app.listen(1337);

console.log('\033[2J');
console.log('Server started!');

推荐答案

(免责声明:我对这些东西仍然陌生,但我的代码中有此功能).

(Disclaimer: I am still new on this stuff, but I have this working in my code).

这里有些错误.

首先,服务器/api中语句的顺序非常重要.需要令牌的路由应位于验证令牌的app.use之后.不需要令牌的路由需要在app.use之前到达.这将包括您的登录路线,因为根据定义它没有令牌.

Firstly, the ordering of statements in your server/api is very important. The routes that require a token should come after the app.use that verifies the token. Routes that do not require a token need to come BEFORE the app.use. This would include your login route, since it doesn't have a token by definition.

固定顺序后,下一个问题(双关语意味)是您在app.use中调用next(),无论令牌是否经过验证.仅当令牌得到验证时,才需要调用next();否则,则需要发送错误消息.结合确定订单的顺序,这可以确保如果令牌无效,则需要处理令牌的获取/发布信息就永远不会得到处理.

Once you have the ordering fixed, the next problem (pun intended) is that you call next() in your app.use, whether the token gets verified or not. You need to call next() only if the token gets verified, and send an error message if it doesn't. In combination with fixing your ordering, this will ensure that your gets/posts that require a token never get processed if the token is invalid.

这篇关于NodeJS Express路由器,在中间件和路由之间传递解码的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆