NodeJS - Passport-JWT,如何设置多个提取器?

时间:2017-10-25 21:31:08

标签: node.js authentication passport.js

以下是我的身份验证策略的配置:

var JWT_STRATEGY_CONFIG = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('MyBearer'),
  secretOrKey: SECRET,
  issuer : ISSUER,
  audience: AUDIENCE,
  passReqToCallback: false
};

我想添加第二个提取器,如果第一个提取器失败,那么我想尝试第二个提取器。为了说明我的想法,这就是我想要做的事情:

var JWT_STRATEGY_CONFIG = {
  jwtFromRequest: [
    ExtractJwt.fromAuthHeaderWithScheme('MyBearer'),
    ExtractJwt.fromUrlQueryParameter('authorization')
  ],
  secretOrKey: SECRET,
  issuer : ISSUER,
  audience: AUDIENCE,
  passReqToCallback: false
};

3 个答案:

答案 0 :(得分:4)

您还可以在ExtractJwt.fromExtractors函数中传递多个提取器

     var JWT_STRATEGY_CONFIG = {   
      secretOrKey: SECRET,   
      issuer : ISSUER,    
      audience: AUDIENCE,    
      passReqToCallback: false,
     jwtFromRequest:ExtractJwt.fromExtractors([ExtractJwt.fromBodyField('auth_token'),ExtractJwt.fromUrlQueryParameter('auth_token')]),

};

答案 1 :(得分:2)

开玩笑吧! 我刚刚意识到我可以轻松创建my own extractor

var cookieExtractor = function(req) {
    var token = null;
    if (req && req.cookies)
    {
        token = req.cookies['jwt'];
    }
    return token;
};

问题已解决!

编辑:如果您的情况与我的情况相同,以下是我制作的代码:

var TokenExtractor = function(req){
  var token = null;

  if ((req.headers && req.headers.authorization) || (req.query && req.query.authorization)) {
    if (req.headers.authorization)
      var parts = req.headers.authorization.split(' ');
    else if (req.query.authorization)
      var parts = req.query.authorization.split(' ');

    if (parts.length == 2) {
      var scheme = parts[0],
        credentials = parts[1];

      if (/^MyBearer$/i.test(scheme)) { //<-- replace MyBearer by your own.
        token = credentials;
      }
    }
  } else if (req.param('token')) {
    token = req.param('token');
    delete req.query.token;
  }

  return token;
}

var JWT_STRATEGY_CONFIG = {
  jwtFromRequest: TokenExtractor,
  secretOrKey: SECRET,
  issuer : ISSUER,
  audience: AUDIENCE,
  passReqToCallback: false
};

此代码的部分灵感来自您可以找到的here

答案 2 :(得分:2)

感谢分享这个简单的解决方案。我在打字稿中采用了你的 NestJs 方法。以防万一有人要找那个。

import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Inject, Injectable } from '@nestjs/common';
import { JWT_SECRET } from '../auth.constants';

/**
 * Extracts the jwt from a cookie
 * @param req Http Request
 */
const cookieExtractor = (req) => {
  let token = null;
  if (req && req.cookies) {
    token = req.cookies.jwt;
  }
  return token;
};

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {

  constructor(@Inject('JWT_SECRET') jwtSecret: string) {
    super({
      jwtFromRequest: ExtractJwt.fromExtractors([
        // Take jwt from http header
        ExtractJwt.fromAuthHeaderAsBearerToken(),
        // Take jwt from cookie
        cookieExtractor
      ]),
      ignoreExpiration: false,
      secretOrKey: jwtSecret,
    });
  }

  async validate(payload: { sub: number, iat: number, exp: number, username: string }): Promise<{ userId: any; username: any }> {
    return { userId: payload.sub, username: payload.username };
  }
}