Ska*_*Ska 2 cookies node.js express jwt
我有一个奇怪的问题,或者我不明白JWT在Express上下文中是如何工作的.
var express = require('express')
var app = express();
var expressJWT = require('express-jwt');
var jwt = require('jsonwebtoken');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var unless = require('express-unless');
app.set('secret', 'some secret');
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use("/", expressJWT({secret:app.get('secret')})
.unless({
path:[
'/',
'/foo',
'/login'
]}
));
// my custom route middleware to verify a token
app.use(function(req, res, next) {
console.log("------------------------------------");
console.log("route middleware to verify a token");
console.log("");
// check header or url parameters or post parameters for token
var token = req.body.access_token || req.query.access_token || req.headers['x-access-token'] || req.cookies.access_token;
console.log("req.cookies.access_token:", req.cookies.access_token);
console.log("token:", token);
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('secret'), function(err, decoded) {
if (err) {
console.log("jwt.verify ERROR")
return res.json({ success: false, message: 'Failed to authenticate token.', err:err });
} else {
console.log("jwt.verify OK")
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
app.get('/', function (req, res) {
res.send('Hello World!. /foo is open, /bar is protected. Login at /login')
})
app.get('/foo', function (req, res) {
res.send('Foo')
})
app.get('/bar', function (req, res) {
res.send('Foo')
})
app.get('/login', function (req, res) {
var username = 'mock_username';
var myToken = jwt.sign({username:username}, app.get('secret'));
res.cookie('access_token', myToken).send("logged in, check cookie");
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
Run Code Online (Sandbox Code Playgroud)
我正在设置JWT令牌并将其保存到/ login路由中的cookie.如果我在浏览器中检查cookie(Chrome中的dev工具),这样就可以设置令牌.
我访问/或/ foo路由(使用除非指定不受保护),浏览器显示正确的结果,但控制台仍然抛出UnauthorizedError.如果我用"除非"明确标记为不受保护的路由,为什么控制台中会显示错误?
我访问/ bar路由(受保护),我的中间件没有被调用,我在控制台和浏览器中都得到了UnauthorizedError.如何确保中间件在此处被触发,如果在我的中间件中确实找到并验证了令牌,如何提供对此路由的访问?
我访问/或/ foo路由(使用除非指定不受保护),浏览器显示正确的结果,但控制台仍然抛出UnauthorizedError.如果我用"除非"明确标记为不受保护的路由,为什么控制台中会显示错误?
通过specifiying unless,你做的/和/foo从路线未受保护的app.use("/", expressJWT(...)唯一,而不是从后面middlewares.该请求也将传递给您的自定义middlware.
我访问/ bar路由(受保护),我的中间件没有被调用,我在控制台和浏览器中都得到了UnauthorizedError.如何确保中间件在此处被触发,如果在我的中间件中确实找到并验证了令牌,如何提供对此路由的访问?
因为,app.use("/", expressJWT(...))当它无法找到时,应用程序崩溃了authorization token.因此,它无法访问您的自定义中间件.
可能的解决方案:1
由于JWT令牌存储在cookie您的案例中,您可以设置getToken方法来获取令牌并让它express-jwt进行验证,并完全删除您的自定义中间件.
例如
app.use("/", expressJWT({
secret : app.get('secret'),
getToken: function fromCookie (req) {
var token = req.cookies.access_token || req.body.access_token || req.query.access_token || req.headers['x-access-token'] ;
if (token) {
return token;
}
return null;
}
}).unless({
path:[
'/',
'/foo',
'/login'
]}
));
Run Code Online (Sandbox Code Playgroud)
并处理错误
app.use(function (err, req, res, next) {
if (err.name === 'UnauthorizedError') {
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
Run Code Online (Sandbox Code Playgroud)
可能的解决方案:2
您可以jwt通过实施自定义中间件(您已经完成)来进行自定义验证.然后根本不需要以下中间件.
删除以下行.
app.use("/", expressJWT({secret:app.get('secret')}).unless(...)
Run Code Online (Sandbox Code Playgroud)
并且为了保护和取消保护路由,unprotected在自定义中间件之前放置路由并protected在自定义中间件之后路由(天真的方式).
希望它能帮到你.
| 归档时间: |
|
| 查看次数: |
12875 次 |
| 最近记录: |