Angular在构建后将“ bearer”字符串添加到身份验证标头

时间:2019-05-23 18:10:47

标签: angular jwt passport.js

在后端(Nodejs + Express)上,我使用JWT令牌保护了路由。在开发环境中,请求中的HTTP授权标头如下所示:

$arr_file_types = ['application/pdf'];

我构建了角度应用程序后,出于某种原因构建的应用程序在标头中添加了“ Bearer”:

Authorization: JWT token_string

请求:

Authorization: Bearer JWT token_string

节点:

 addTemplate(template: ITemplate): Observable<ISuccessMsgResponse> {
    return this.http.post<ISuccessMsgResponse>(`${this.ULR}template`, template, {
      headers: new HttpHeaders({
        'Authorization': this.token.getToken()
      })
    });
  }

护照:

.post(passport.authenticate('jwt', {session: false}), (req, res) => {
     // Code to execute
}

如果我尝试使用与开发中相同的Authorization标头格式进行请求,则一切正常。因此问题出在Angular的内置版本中,该版本在Authorization标头中添加了“ Bearer”。有谁知道为什么会这样以及我该如何解决?

2 个答案:

答案 0 :(得分:1)

我知道已经过了半年,但仍然只是想发布我的问题的答案。 在这种情况下的问题是,在开发中,HttpClient没有在'Authorization'标头的开头附加'Bearer'字符串,但是在生产中将其包括在内。 发展:JWT token_string 生产:Bearer JWT token_string 解决方案非常烦人,因为我不得不手动在构建脚本中找到Authorization Header所在的部分,并删除设置了标头的字符串中的“ JWT”,因为看起来其中需要Bearer。 >

之前:Bearer JWT token_string 之后:Bearer token_string

在后端,还必须修改用于提取的字符串。 之前:

    let opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');
    opts.secretOrKey = config.secret;
    passport.use(new JwtStrategy(opts, (jwtPayload, done) => {
        User.findById(jwtPayload._id, (err, user) => {
            if(err) {
                return done(err, false);
            }
            if(user) {
                return done(null, user);
            } else {
                return done(null, false);
            }
        });
    }));

之后:

    let opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('bearer');
    opts.secretOrKey = config.secret;
    passport.use(new JwtStrategy(opts, (jwtPayload, done) => {
        User.findById(jwtPayload._id, (err, user) => {
            if(err) {
                return done(err, false);
            }
            if(user) {
                return done(null, user);
            } else {
                return done(null, false);
            }
        });
    }));

我不在这个主题中导出,但是我真的不明白为什么不会在开发中(如在生产中)添加“ Bearer”的原因。可能只是一个错误(Angular 7)。 IDK。

答案 1 :(得分:1)

距离上次回答还有很长一段时间,但它可能对某人有所帮助 - 并防止一些痛苦,就像我的一样,直到我想出一个“解决方案”。

简而言之,请求是:

getUserProfile(){
this.loadCurrentToken();
const headers = new HttpHeaders({
  'Content-Type': 'application/json',
  Authorization: this.authToken,
});
console.log(headers);
return this.http.get('/users/profile', {headers});
}

我面临的问题是,在开发模式 (ng serve) 中,在授权标头处生成的令牌的形式为:JWT eyfhik4u5h4tb...等,在生产模式 (ng build --prod),'Bearer' 词被添加为前缀,所以现在令牌是:Bearer JWT eyfhik4u5h4tb...等(就像上面的答案所暗示的那样)

当然这是标准,但也不想从 fromAuthHeaderWithScheme('jwt') 方法更改为提取方法,意思是:

let opts ={};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderWithScheme('jwt');
opts.secretOrKey = config.secret;
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
    User.getUserById(jwt_payload._id, (err, user) => {
        if(err){
            return done(err, false);
        }

        if(user){
           return done(null, user); 
        } else {
            return done(null, false);
        }
    });
}));

...对于其他内容,让我们说 fromAuthHeaderWithScheme(auth_scheme)fromAuthHeaderAsBearerToken() 并继续进行相应的更改。

所以,我所做的,并且到目前为止在生产和开发模式下都运行良好,是尝试获得一个“干净”的令牌 - 以 JWT eyfhik4u5h4tb...等的形式无论是开发环境还是生产环境。

我的方法是这样修改 //node_modules/passport-jwt/lib/auth_headers.js 文件:

'use strict';

var re = /(\S+)\s+(\S+)/;



function parseAuthHeader(hdrValue) {
    if (typeof hdrValue !== 'string') {
        return null;
    }

    /* ADDED THIS LINE */
    hdrValue = hdrValue.substring(hdrValue.indexOf('JWT') + 0);
    /* --------------- */

    var matches = hdrValue.match(re);
    // console.log(hdrValue);
    return matches && { scheme: matches[1], value: matches[2] };
}



module.exports = {
    parse: parseAuthHeader
};

所以,现在,提取器将只关心以 JWT 开头的令牌部分,并忽略不记名前缀 - 或任何前缀 - 如果存在。

当然,使用这种方法应该记住的一点是,在部署应用程序时,应该包括特定的、更改的、passport-jwt 模块,因为在 npm-install 时,该模块将重新启动/更新等,并且不会工作。