无法使用 express-jwt 和 MEAN 堆栈在服务器端验证令牌
Unable to validate token on server side using express-jwt with MEAN stack
我正在尝试使用 express-jwt 来保护我的 API。我正在使用 MEAN (Angular 4) 堆栈。我尝试了以下代码的多种变体,但无法弄清楚为什么我无法验证令牌。
下面列出的代码 return 是 401 Unauthorized to the client
。其他变体 return 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;
}
}));
问题:
- 如果 header 中的令牌有效,是否设置 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);
});
});
注意:在 returns UnauthorizedError: Format is Authorization: Bearer [token]
.
正上方代码的第一行后添加 jwt({secret: 'test'}),
用户模型:
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);
}
在服务器端你可以这样做
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
}
};
我正在尝试使用 express-jwt 来保护我的 API。我正在使用 MEAN (Angular 4) 堆栈。我尝试了以下代码的多种变体,但无法弄清楚为什么我无法验证令牌。
下面列出的代码 return 是 401 Unauthorized to the client
。其他变体 return 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;
}
}));
问题:
- 如果 header 中的令牌有效,是否设置 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);
});
});
注意:在 returns UnauthorizedError: Format is Authorization: Bearer [token]
.
jwt({secret: 'test'}),
用户模型:
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);
}
在服务器端你可以这样做
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
}
};