无法使用带有 MEAN 堆栈的 express-jwt 在服务器端验证令牌
Posted
技术标签:
【中文标题】无法使用带有 MEAN 堆栈的 express-jwt 在服务器端验证令牌【英文标题】:Unable to validate token on server side using express-jwt with MEAN stack 【发布时间】:2017-12-13 18:29:00 【问题描述】:我正在尝试使用 express-jwt 保护我的 api。我正在使用 MEAN (Angular 4) 堆栈。我尝试了以下代码的许多变体,但无法弄清楚为什么我无法验证令牌。
下面列出的代码返回401 Unauthorized to the client
。其他变体返回UnauthorizedError: Format is Authorization: Bearer [token]
。有人看到下面的代码有什么问题吗?
服务器端代码
在我的 app.ts 文件中,我有以下内容:
app.use('/api/volunteers/', jwt(
secret: 'test',
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring (req)
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
// console.log(req.headers.authorization.split(' ')[0] === 'Bearer')
return req.headers.authorization.split(' ')[1];
else if (req.query && req.query.token)
return req.query.token;
return null;
));
问题:
-
如果标头中的令牌有效,这是否设置 req.user?
我需要显式调用 getToken() 吗?
在我的 routes.ts 文件中,我有:
app.get('/api/volunteers',
function(req, res)
console.log('req user ' + req.user);
// auth
if (!req.user)
return res.sendStatus(401);
// logic
Volunteer.find(, (err, docs) =>
if (err)
res.status(400).send(err);
return console.error(err);
res.json(docs);
);
);
注意:在上面代码的第一行之后添加jwt(secret: 'test'),
会返回UnauthorizedError: Format is Authorization: Bearer [token]
。
用户模型:
import * as bcrypt from 'bcryptjs';
import * as mongoose from 'mongoose';
const userSchema = new mongoose.Schema(
username: String,
email: type: String, unique: true, lowercase: true, trim: true ,
password: String,
role: String
);
const User = mongoose.model('User', userSchema);
export default User;
用户处理程序:
import BaseHandler from './base';
import User from '../models/user';
import * as jwt from 'jsonwebtoken';
import * as dotenv from 'dotenv';
import 'zone.js';
import 'reflect-metadata';
export default class UserHandler extends BaseHandler
model = User;
login = (req, res) =>
this.model.findOne( email: req.body.email , (err, user) =>
if (!user) return res.sendStatus(403);
user.comparePassword(req.body.password, (error, isMatch) =>
if (!isMatch) return res.sendStatus(403);
// why sign with user
// why do I need test
const token = jwt.sign(user: user, 'test');
res.status(200).json( token: token );
);
);
;
客户端代码
我服务的一部分:
constructor(private http: Http)
this.headers = new Headers( 'Content-Type': 'application/json' );
this.headers.append('authorization', localStorage.token);
this.options = new RequestOptions( headers: this.headers );
getVolunteers(): Observable<Volunteer[]>
return this.http.get('/api/volunteers', this.options)
.map((res: Response) => res.json())
.catch(handleError);
【问题讨论】:
如果标头中的令牌有效,是否设置 req.user? Ans: 需要用户自己设置 req.user UnauthorizedError: Format is Authorization: Bearer [token] 这个错误是因为app.ts中有下面这行 return req.headers.authorization.split(' ')[1];您必须返回整个令牌,包括“Bearer” 【参考方案1】:在服务器端你可以这样做
var authentication = require('./auth');
router.route('/create')
.all(authentication)
.post(function(req, res)
// Your Code
);
并在 auth.js 中编写以下代码
var jwt = require('jwt-simple'),
common = require('./common'),
secretKey = require('./key');
module.exports = function (req, res, next)
var token = req.headers['authorization'];
if (token)
try
var token = jwt.decode(token, secretKey);
var user = token.user; // Get user from token in your way
return next();
catch (err)
// Throw error
else
// Throw error
;
【讨论】:
谢谢!我最终使用了 jwt-simple 并遵循这个例子而不是 express-jwt以上是关于无法使用带有 MEAN 堆栈的 express-jwt 在服务器端验证令牌的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 MEAN 堆栈连接到 Mongodb.atlas 集群
无法让 NODE_ENV 在开班时粘在我的 MEAN 堆栈上