JWT UnauthorizedError:未找到授权令牌(带有cookie的GET请求) [英] JWT UnauthorizedError: No authorization token was found (GET request with cookie)

查看:856
本文介绍了JWT UnauthorizedError:未找到授权令牌(带有cookie的GET请求)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题,或者也许我不了解JWT在Express上下文中的工作方式.

I have a strange problem, or maybe I don't understand how JWT works in Express context.

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!')
})

我正在设置一个JWT令牌,并将其保存到/login路由中的cookie中. 如果我在浏览器中检查Cookie(Chrome中的开发工具),则会设置令牌并设置令牌.

I'm setting up a JWT token and saving it to cookie in the /login route. This works and the token is set if I check cookie in the browser (dev tools in Chrome).

  • 我访问/或/foo 路由(除非另有指定,否则不受保护),浏览器显示正确的结果,但控制台仍会抛出 UnauthorizedError .如果我用"unless"将其明确标记为不受保护的路由,为什么在控制台中会显示错误?

  • I visit the / or /foo route (unprotected as specified with unless), and browser displays correct result, but the console still throws the UnauthorizedError. Why is the error showing in the console if I explicitly marked this as unprotected route with "unless"?

我访问了/bar 路线(受保护),未调用我的中间件,在控制台和浏览器中都收到了 UnauthorizedError .我如何确保中间件确实在这里被触发,并且如果在中间件中确实找到并验证了令牌,如何提供对此路由的访问?

I visit /bar route (protected), my middleware is not being called, I get the UnauthorizedError both in console and the browser. How do I make sure the middleware does get triggered here, and how do I provide the access to this route if the token is indeed found and verified in my middleware?

推荐答案

我访问了/或/foo路由(除非另有指定,否则不受保护),浏览器显示正确的结果,但控制台仍会抛出UnauthorizedError.如果我用"unless"明确地将其标记为不受保护的路由,为什么在控制台中会显示错误?

I visit the / or /foo route (unprotected as specified with unless), and browser displays correct result, but the console still throws the UnauthorizedError. Why is the error showing in the console if I explicitly marked this as unprotected route with "unless"?

通过指定unless,您使//foo路由仅不受app.use("/", expressJWT(...)的保护,而不受后续middlewares的保护.该请求也将传递到您的自定义中间件.

By specifiying unless, you made the / and /foo route unprotected from app.use("/", expressJWT(...) only, not from subsequent middlewares. The request will pass to your custom middlware too.

我访问/bar路由(受保护),未调用中间件,在控制台和浏览器中均收到UnauthorizedError.如何确保中间件确实在这里被触发,并且如果在中间件中确实找到并验证了令牌,如何提供对这条路由的访问?

I visit /bar route (protected), my middleware is not being called, I get the UnauthorizedError both in console and the browser. How do I make sure the middleware does get triggered here, and how do I provide the access to this route if the token is indeed found and verified in my middleware?

因为,当找不到authorization token时,应用程序在app.use("/", expressJWT(...))崩溃了.因此,它无法到达您的自定义中间件.

Because, the application got crashed at app.use("/", expressJWT(...)), when it could not find authorization token. Hence, it could not reach to your custom middleware.

可能的解决方案:1

由于在您的情况下JWT令牌存储在cookie中,因此您可以设置getToken方法来获取令牌,并让express-jwt对其进行验证,然后完全删除自定义中间件.

Since JWT token is stored in cookie in your case, you can set getToken method to get the token and let express-jwt to verify it, and remove your custom middleware altogether.

例如

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'
    ]}
));

并处理错误

app.use(function (err, req, res, next) {
  if (err.name === 'UnauthorizedError') {
    return res.status(403).send({
      success: false,
      message: 'No token provided.'
    });
  }
});

可能的解决方案:2

您可以通过实现自定义中间件(已经完成)来执行自定义jwt验证.这样就完全不需要以下中间件了.

You can do the custom jwt verification by implementing your custom middleware (that you have already done). Then there is no need of the following middleware at all.

删除以下行.

app.use("/", expressJWT({secret:app.get('secret')}).unless(...)

为保护和取消保护路由,请在自定义中间件之前放置unprotected路由,在自定义中间件之后放置protected路由(幼稚的方式).

And for protecting and unprotecting the routes, put unprotected routes before the the custom middleware and protected route after custom middleware (naive way).

希望它对您有帮助.

这篇关于JWT UnauthorizedError:未找到授权令牌(带有cookie的GET请求)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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