我目前正在使用 typescript、WebStorm、passport 和 jwt 为 node.js 微服务应用程序开发身份验证服务。在尝试将路由添加到“/api/login”时,我注意到智能感知似乎没有获取 req.user 的用户对象或 req.header.authorization 的授权对象。例如,以下方法不起作用,因为它找不到用户对象:
private generateToken(req: Request, res: Response, next: NextFunction){
req.token = jwt.sign({
id: req.user.id,
firstname: req.user.firstname,
lastname: req.user.lastname,
roles: req.user.roles
}, process.env.AUTH_KEY, {
expiresIn: "7d"
});
return next();
}
我正在使用来自 express 的 Request 对象:
import { NextFunction, Request, Response, Router } from "express";
我需要使用不同的请求对象吗?
此外,如果我需要对某些 api 路由强制进行身份验证但锁定其他路由,应该如何使用 passport-jwt 来完成?我知道有一个 express-unless 包可以用于 express-jwt。
最佳答案
不知道为什么这个问题被否决了,可能是因为它应该是两个不同的问题。
您可以扩展 Express 的类型声明。
扩展快速类型定义
将文件 library-ext.d.ts
添加到您的源目录中。
declare module 'express' {
export interface Request {
user?: any;
}
}
对于 req.header.authorization
尝试:req.headers['authorization']。注意“s”。
关于通用认证
这取决于您的注册用户是否也可以使用 guest
路由。如果您从不需要在访客路由上进行身份验证,那么只需在经过身份验证的路由上注册 Passport 身份验证中间件,或者将路由拆分到单独的路由器中。这非常简单,只需搜索堆栈溢出或在文档中查找即可。
更复杂的情况是,当您需要经过身份验证的用户和未经身份验证的用户访问一条路线时 - 考虑访客或经过身份验证的客户向购物车添加东西。不幸的是 passport-jwt
当 token 不在 authorzation header 中时以 401 拒绝,所以我发现最简单的方法是使用中间件添加一个已知值来表示匿名请求。然后只需确保中间件在受影响的路由中进行 Passport 身份验证之前。这是一个让你继续前进的片段:
核心控制
class CoreCtrl {
simulateAnonymous(req, res, next) {
if (!req.headers.authorization) {
req.headers.authorization = 'Bearer guest-token';
}
return next();
}
}
然后在您的快速设置中的某处
setupRouters() {
// the public and admin routers are bound to the application
const coreCtrl = new CoreCtrl(this.serverOpts);
const anonymousCtrl = coreCtrl.simulateAnonymous.bind(coreCtrl);
this.routers.admin.use(anonymousCtrl);
this.routers.admin.use(passport.authenticate('UserBearer', { session: false }));
this.routers.public.use(anonymousCtrl);
this.routers.public.use(passport.authenticate('CustomerBearer', { session: false }));
}
请注意,我在这里为公共(public)和管理员设置了单独的路由器,这不是必需的,只是为了说明如何操作。
然后在bearer strategy中,你会有一些类似的代码。
/**
* Run the strategy
*
* @param token {String} The JWT Token
* @param done {Callback} Callback function
*/
exec(token:string, done):Promise<any> {
// this is the workaround to support not passing a token for guest users.
if (token === 'guest-token') {
return done(null, {
userId: 'guest',
roles: ['guest']
});
}
// otherwise decode the token and find the user.
}
最后,在后来的一些中间件中,您可以检查“ guest ”角色是否可以访问 protected 资源。我建议使用 acl
模块来管理基于角色的 ACL 列表。
关于使用 Passport 和 typescript : cannot find req. 用户的 Node.js 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43986460/