Аутентификация API node с паспорт-jwt

Я пытаюсь настроить JWT-аутентификацию с помощью паспорта-jwt. Я думаю, что я сделал правильные шаги, но тест GET не удастся, и я не знаю, как его отладить.

Вот что я сделал:

  • установить паспорт-jwt прямо из документа как можно больше

    var jwtOptions = {
        secretOrKey: 'secret',
        issuer: "accounts.examplesoft.com",  // wasn't sure what this was, so i left as defaulted in the doc
        audience: "yoursite.net"   // wasn't sure what this was, so i left as defaulted in the doc
      };
    
    jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeader();
    
    passport.use(new JwtStrategy(jwtOptions, function(jwt_payload, done) {
      User.findOne({id: jwt_payload.sub}, function(err, user) {
        if (err) {
            return done(err, false);
        }
        if (user) {
            done(null, user);
        } else {
            done(null, false);
            // or you could create a new account
        }
      });
    }));
    
  • Добавлен результат токена в конечную точку пользователя/пользователя

    var jwt = require('jsonwebtoken');
    // ...
    
    exports.postLogin = function(req, res, next) {
      passport.authenticate('local', function(err, user, info) {
        if (err) throw err;
        if (!user) {
            return res.send({ msg: 'Login incorrect' });
        }
        req.logIn(user, function(err) {
            if (err) throw err;
            var secretOrKey = jwtOptions.secretOrKey;
            var token = jwt.sign(user, secretOrKey, {
                expiresIn: 631139040 // 20 years in seconds
            });
            res.send({ user: user, jwtToken: "JWT " + token });
        });
      })(req, res, next);
    };
    

Все хорошо смотрелось здесь. Я могу войти в систему у пользователя (с использованием паспортного локального сертификата), и ответ был я надеялся...

{      "пользователь": {         msgstr ""          "электронная почта": "[email protected]",          "пароль": "$ 2a $10 $zd... и т.д.",          "__v": 0,     },      "jwtToken": "JWT eyJ0eXAiOiJ.... и т.д." }

Я создал незащищенный тестовый маршрут, подобный этому...

// in my routes file
app.get('/user/tokenTest', user.tokenTest);

И в моем контроллере простая конечная точка...

exports.tokenTest = function(req, res) {
    console.log(req.headers);
    res.send("token test!!");
};

И GET-ing, который отлично работает.

  1. Но затем я пытаюсь защитить этот маршрут следующим образом:

    app.get('/user/tokenTest', passport.authenticate('jwt', { session: false }),
        user.tokenTest);
    

Когда я это сделаю, ничего, кроме грусти. Я отправляю запрос следующим образом:

curl -k 'https://localhost:3443/user/tokenTest' -H 'Authorization: JWT eyJ0eXAiOiJ... etc.' 

И всегда, всегда получайте 401:

Несанкционированное

Журналы консоли в контроллере, похоже, не выполняются, также не регистрируются в методе стратегии passport.use. Я настраивал и настраивал, но я немного потерялся. Пример паспорта-jwt просто поставляет пример, и практически никакой другой помощи.

Пожалуйста, любые идеи об ошибке, которую я делаю выше, или, по крайней мере, о том, как сделать отладку

Ответы

Ответ 1

Для любой бедной души, которая следует за мной здесь: документ паспорт-jwt подразумевает, что заголовок auth должен выглядеть так...

Авторизация: JWT JSON_WEB_TOKEN_STRING.....

Это оказалось ошибочным (для меня, во всяком случае).

К счастью, благодаря этой статье я смог узнать, как построен токен. (Префикс токена до первого "." - это кодировка base64 схемы. Это "JWT" на фронте представляло собой шум, который мешал валидации работать.

Итак, исправление заключалось в том, чтобы изменить токен, возвращаемый пользовательским контроллером, из:

    res.send({ user: user, jwtToken: "JWT " + token });

К более простому:

    res.send({ user: user, jwtToken: token });

Уф. Это я, или это действительно облом, как неадекватно эти вещи объясняются во многих документах пакета node