如何从 @types/jsonwebtoken 向 JwtPayload 类型添加额外的属性
How to add additional properties to JwtPayload type from @types/jsonwebtoken
我是 typescript 的新手,正在尝试移植 express 应用程序以使用 typescript。服务器将 JWT 用于 authentication/authorisation,我有一个实用函数可以解码和验证给定的令牌。该函数包含在一个承诺中,因此我可以在实现它的中间件中使用 async/await。
import httpError from 'http-errors';
import jwt from 'jsonwebtoken';
const { ACCESS_TOKEN_SECRET } = process.env;
export function verifyAccessToken(token: string): Promise<jwt.JwtPayload | undefined> {
return new Promise((resolve, reject) => {
jwt.verify(token, ACCESS_TOKEN_SECRET as string, (err, payload) => {
if (err) {
return reject(new httpError.Unauthorized());
}
return resolve(payload);
});
});
}
此函数工作正常,但我在 JWT 中有其他信息。具体来说,我有一个 role
属性,因此有效负载的类型为:
{
sub: string, // ID issued by mongoose
role: string, // My new information that is causing error
iat: number,
exp: number
}
我的问题是来自@types/jsonwebtoken 的 JwtPayload 的类型不包含 role
因此当 Promise 解决时,我在尝试访问 payload.role
时收到打字稿错误身份验证中间件。
import { RequestHandler } from 'express';
import httpError from 'http-errors';
import { verifyAccessToken } from '../utils'
export const authenticate: RequestHandler = async (req, res, next) => {
try {
const authHeader = req.headers['authorization'] as string;
if (!authHeader) {
throw new httpError.Unauthorized();
}
const accessToken = authHeader.split(' ')[1];
if (!accessToken) throw new httpError.Unauthorized();
const payload = await verifyAccessToken(accessToken);
// If I try to access payload.role here I get an error that type JwtPayload does not contain 'role'
next();
} catch (err) {
next(err);
}
};
如何扩展 JwtPayload 类型以添加角色 属性?我试图定义我自己的自定义类型并完全覆盖从 jwt.verify()
返回的类型,但这会引发一个错误,没有重载匹配此调用。
interface MyJwtPayload {
sub: string;
role: string;
iat: number;
exp: number;
}
// ... then in the utility function replace jwt.verify() call with
jwt.verify(token, ACCESS_TOKEN_SECRET as string, (err, payload: MyJwtPayload) => {
谢谢。
您应该可以通过 declaration merging 实现。
在您的代码中的某处添加:
declare module "jsonwebtoken" {
export interface JwtPayload {
role: string;
}
}
这应该可以根据需要扩展界面。
重新声明带有扩展负载的 jsonwebtoken
模块,然后 parse/cast 相应地验证令牌。
import * as jwt from 'jsonwebtoken'
declare module 'jsonwebtoken' {
export interface UserIDJwtPayload extends jwt.JwtPayload {
userId: string
}
}
export const userIdFromJWT = (jwtToken: string): string | undefined => {
try {
const { userId } = <jwt.UserIDJwtPayload>jwt.verify(jwtToken, process.env.JWT_COOKIE_SECRET || 'MISSING_SECRET')
return userId
} catch (error) {
return undefined
}
}
我是 typescript 的新手,正在尝试移植 express 应用程序以使用 typescript。服务器将 JWT 用于 authentication/authorisation,我有一个实用函数可以解码和验证给定的令牌。该函数包含在一个承诺中,因此我可以在实现它的中间件中使用 async/await。
import httpError from 'http-errors';
import jwt from 'jsonwebtoken';
const { ACCESS_TOKEN_SECRET } = process.env;
export function verifyAccessToken(token: string): Promise<jwt.JwtPayload | undefined> {
return new Promise((resolve, reject) => {
jwt.verify(token, ACCESS_TOKEN_SECRET as string, (err, payload) => {
if (err) {
return reject(new httpError.Unauthorized());
}
return resolve(payload);
});
});
}
此函数工作正常,但我在 JWT 中有其他信息。具体来说,我有一个 role
属性,因此有效负载的类型为:
{
sub: string, // ID issued by mongoose
role: string, // My new information that is causing error
iat: number,
exp: number
}
我的问题是来自@types/jsonwebtoken 的 JwtPayload 的类型不包含 role
因此当 Promise 解决时,我在尝试访问 payload.role
时收到打字稿错误身份验证中间件。
import { RequestHandler } from 'express';
import httpError from 'http-errors';
import { verifyAccessToken } from '../utils'
export const authenticate: RequestHandler = async (req, res, next) => {
try {
const authHeader = req.headers['authorization'] as string;
if (!authHeader) {
throw new httpError.Unauthorized();
}
const accessToken = authHeader.split(' ')[1];
if (!accessToken) throw new httpError.Unauthorized();
const payload = await verifyAccessToken(accessToken);
// If I try to access payload.role here I get an error that type JwtPayload does not contain 'role'
next();
} catch (err) {
next(err);
}
};
如何扩展 JwtPayload 类型以添加角色 属性?我试图定义我自己的自定义类型并完全覆盖从 jwt.verify()
返回的类型,但这会引发一个错误,没有重载匹配此调用。
interface MyJwtPayload {
sub: string;
role: string;
iat: number;
exp: number;
}
// ... then in the utility function replace jwt.verify() call with
jwt.verify(token, ACCESS_TOKEN_SECRET as string, (err, payload: MyJwtPayload) => {
谢谢。
您应该可以通过 declaration merging 实现。
在您的代码中的某处添加:
declare module "jsonwebtoken" {
export interface JwtPayload {
role: string;
}
}
这应该可以根据需要扩展界面。
重新声明带有扩展负载的 jsonwebtoken
模块,然后 parse/cast 相应地验证令牌。
import * as jwt from 'jsonwebtoken'
declare module 'jsonwebtoken' {
export interface UserIDJwtPayload extends jwt.JwtPayload {
userId: string
}
}
export const userIdFromJWT = (jwtToken: string): string | undefined => {
try {
const { userId } = <jwt.UserIDJwtPayload>jwt.verify(jwtToken, process.env.JWT_COOKIE_SECRET || 'MISSING_SECRET')
return userId
} catch (error) {
return undefined
}
}