2017-01-27 1 views
0

У меня странная проблема, или, может быть, я не понимаю, как работает JWT в контексте Express.JWT UnauthorizedError: не найдено авторизационного токена (запрос GET с файлом cookie)

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 и сохраняю его в файле cookie в/логином. Это работает, и токен установлен, если я проверяю cookie в браузере (инструменты разработчика в Chrome).

  • я посещаю/или /Foo маршрут (незащищенный, как указано с), если, и браузер отображает правильный результат, но консоль по-прежнему бросает UnauthorizedError. Почему ошибка отображается в консоли, если я явно обозначил это как незащищенный маршрут с помощью «если»?

  • посещает /бар маршрут (защищенный), мой промежуточный слой не вызываются, я получаю UnauthorizedError как в консоли и в браузере. Как я могу убедиться, что промежуточное ПО запускается здесь, и как я могу предоставить доступ к этому маршруту, если токен действительно найден и проверен в моем промежуточном программном обеспечении?

+0

потому что вы не прикрепляли 'если' с другим промежуточным программным обеспечением. –

+0

Какие из них? Это ответ на первый вопрос из двух. Пожалуйста, поставьте его в форме ответа, чтобы я мог подняться и дать вам очки :) – Ska

ответ

1

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"?

По specifiying unless, вы сделали / и /foo маршрут незащищенный от app.use("/", expressJWT(...) только не с последующей middlewares. Запрос также будет передан в ваше обычное медиа-приложение.

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?

Так, приложение получил разбился на 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' 
    ]} 
)); 

и обработать ошибку

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

Возможное решение: 2

Вы можете сделать проверку пользовательских jwt путем реализации пользовательского ПО промежуточного (что вы уже сделали). Тогда нет необходимости в следующем промежуточном программном обеспечении.

Удалить следующую строку.

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

И для защиты и снятия защиты маршрутов, положить unprotected маршруты до проведения Обычай промежуточного слоя и protected маршрут после пользовательского ПО промежуточного слоя (наивный способ).

Надеюсь, это поможет вам.

Смежные вопросы