【问题标题】:Passport JWT authentication extract tokenPassport JWT 身份验证提取令牌
【发布时间】:2019-01-22 19:51:14
【问题描述】:

我正在使用 express 和 jwt-simple 作为中间件 api 来处理登录/注册和身份验证请求。我正在尝试创建一个 .well-known 端点,以便其他 api 可以根据发送的令牌对请求进行身份验证。

这是我的策略:

module.exports = function() {
    const opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
    opts.secretOrKey = securityConfig.jwtSecret;
    passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
        // User.where('id', jwt_payload.id).fetch({withRelated: 'roles'})
        console.log('jwt_payload', jwt_payload)
            User.where('id', jwt_payload.id).fetch()
            .then(user => user ? done(null, user) : done(null, false))
            .catch(err => done(err, false));
    }));
};

这是我的登录路径:

router.post('/login', function(req, res) {
    const {username, password} = req.body;
    Promise.coroutine(function* () {
        const user = yield User.where('username', username).fetch();

    if(user) {
        const isValidPassword = yield user.validPassword(password);
        if (isValidPassword) {
            let expires = (Date.now() / 1000) + 60 * 30
            let nbf = Date.now() / 1000
            const validatedUser = user.omit('password');

            // TODO: Verify that the encoding is legit..
            // const token = jwt.encode(user.omit('password'), securityConfig.jwtSecret);
            const token = jwt.encode({ nbf: nbf, exp: expires, id: validatedUser.id, orgId: validatedUser.orgId }, securityConfig.jwtSecret)
            res.json({success: true, token: `JWT ${token}`, expires_in: expires});
        } else {
            res.status(401);
            res.json({success: false, msg: 'Authentication failed'});
        }
    } else {
        res.status(401);
        res.json({success: false, msg: 'Authentication failed'});
    }
    })().catch(err => console.log(err));
});

这是我的 .well-known 路线:

router.get('/.well-known', jwtAuth, function(req, res) {
    // TODO: look over res.req.user. Don't seem to be the way to get those parameters.
    // We dont take those parameters from the decrypted JWT, we seem to grab it from the user in DB.
    const { id, orgId } = res.req.user.attributes;
    console.log("DEBUG: userId", id)
    console.log("DEBUG: USER", res.req.user)
    res.json({
        success: true,
        userId: id,
        orgId
    });
});

这是我的 jwtAuth() 函数:

const passport = require('passport');
module.exports = passport.authenticate('jwt', { session: false });

我将如何在路由函数中实际获取令牌并解密它?所有这一切现在都有效,如果它是真的,它会进行身份验证,但是我需要能够解密令牌以发回存储的值。不知道 res.req.user.attributes 是从哪里来的,这个是token吗?

【问题讨论】:

    标签: node.js express jwt jwt-simple


    【解决方案1】:

    查看passport-jwt 和您的passport-config(或您初始化护照的任何地方)设置 JWT 策略:

    const JwtStrategy = require('passport-jwt').Strategy;
    const ExtractJwt = require('passport-jwt').ExtractJwt;
    
    const jwtAuth = (payload, done) => {
     const user = //....find User in DB, fetch roles, additional data or whatever
     // do whatever with decoded payload and call done
     // if everything is OK, call
     done(null, user);
     //whatever you pass back as "user" object will be available in route handler as req.user
    
     //if your user does not authenticate or anything call
     done(null, false);
    }
    
    const apiJwtOptions: any = {};
    apiJwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
    apiJwtOptions.algorithms = [your.jwt.alg];
    apiJwtOptions.secretOrKey = your.jwt.secret;
    //apiJwtOptions.issuer = ???;
    //apiJwtOptions.audience = ???;
    passport.use('jwt-api', new JwtStrategy(apiJwtOptions, jwtAuth));
    

    如果您只想解码令牌,请在jwtAuth 中调用done(null, payload)

    然后在您的路由文件中,当您想要保护端点并获得有关用户的信息时,请使用:

    const router = express.Router();
    router.use(passport.authenticate('jwt-api', {session: false}));
    

    在处理程序中,您应该有req.user 可用。它可以配置为 req 的哪个属性存储来自 auth 的数据,req.user 只是默认值。

    【讨论】:

    • 您好,抱歉耽搁了。我注意到我正在使用 passport-jwt 来获取 jwtHeader 并秘密提取/解码。我在 /login 和 /register 上使用 simple-jwt。我的问题是,如果我登录并将令牌返回给 webclient,然后在尝试根据返回的 JWT 调用身份验证路由半秒后,它不会返回任何内容(没有经过身份验证)。但是等待 2 秒并调用它,它可以工作......似乎将 jwt 保存到护照时有延迟
    • 你有几分钟的私人聊天时间吗?
    • 我不在家,正在度假。回来时我们可以聊天。
    • 这对您来说仍然是一个问题还是您在此期间解决了这个问题??
    • 我不知道在回调中返回用户对象作为第二个参数时,我们可以稍后从req.user获取信息。谢谢!
    猜你喜欢
    • 2018-05-07
    • 2019-03-28
    • 2017-05-13
    • 2016-01-02
    • 2017-10-22
    • 1970-01-01
    • 2020-07-07
    • 2019-08-04
    • 2020-08-23
    相关资源
    最近更新 更多