-
Notifications
You must be signed in to change notification settings - Fork 30.5k
[jsonwebtoken]: Add standard fields #53435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
26b1f67
3eb3183
2942d3c
ddee82f
7196808
eeba270
9c619fc
e2ab849
d5640a0
85afc23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |||||||||
| // Linus Unnebäck <https://github.com/LinusU> | ||||||||||
| // Ivan Sieder <https://github.com/ivansieder> | ||||||||||
| // Piotr Błażejewicz <https://github.com/peterblazejewicz> | ||||||||||
| // Nandor Kraszlan <https://github.com/nandi95> | ||||||||||
| // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped | ||||||||||
|
|
||||||||||
| /// <reference types="node" /> | ||||||||||
|
|
@@ -62,7 +63,7 @@ export interface SignOptions { | |||||||||
| jwtid?: string; | ||||||||||
| mutatePayload?: boolean; | ||||||||||
| noTimestamp?: boolean; | ||||||||||
| header?: object; | ||||||||||
| header?: JwtHeader; | ||||||||||
| encoding?: string; | ||||||||||
| } | ||||||||||
|
|
||||||||||
|
|
@@ -98,24 +99,48 @@ export type VerifyErrors = | |||||||||
| | JsonWebTokenError | ||||||||||
| | NotBeforeError | ||||||||||
| | TokenExpiredError; | ||||||||||
| export type VerifyCallback = ( | ||||||||||
| export type VerifyCallback<T = JwtPayload> = ( | ||||||||||
| err: VerifyErrors | null, | ||||||||||
| decoded: object | undefined, | ||||||||||
| decoded: T | undefined, | ||||||||||
| ) => void; | ||||||||||
|
|
||||||||||
| export type SignCallback = ( | ||||||||||
| err: Error | null, encoded: string | undefined | ||||||||||
| ) => void; | ||||||||||
|
|
||||||||||
| // standard names https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1 | ||||||||||
| export interface JwtHeader { | ||||||||||
| alg: string; | ||||||||||
| alg: string | Algorithm; | ||||||||||
| typ?: string; | ||||||||||
| cty?: string; | ||||||||||
| crit?: Array<string | Exclude<keyof JwtHeader, 'crit'>>; | ||||||||||
| kid?: string; | ||||||||||
| jku?: string; | ||||||||||
| x5u?: string; | ||||||||||
| x5u?: string | string[]; | ||||||||||
| 'x5t#S256'?: string; | ||||||||||
| x5t?: string; | ||||||||||
| x5c?: string | string[]; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // standard claims https://datatracker.ietf.org/doc/html/rfc7519#section-4.1 | ||||||||||
| export interface JwtPayload { | ||||||||||
| [key: string]: any; | ||||||||||
| iss?: string; | ||||||||||
| sub?: string; | ||||||||||
| aud?: string | string[]; | ||||||||||
| exp?: number; | ||||||||||
| nbf?: number; | ||||||||||
| iat?: number; | ||||||||||
| jti?: string; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| export interface Jwt { | ||||||||||
| header: JwtHeader; | ||||||||||
| payload: JwtPayload; | ||||||||||
| signature: string; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // https://github.com/auth0/node-jsonwebtoken#algorithms-supported | ||||||||||
| export type Algorithm = | ||||||||||
| "HS256" | "HS384" | "HS512" | | ||||||||||
| "RS256" | "RS384" | "RS512" | | ||||||||||
|
|
@@ -177,7 +202,8 @@ export function sign( | |||||||||
| * [options] - Options for the verification | ||||||||||
| * returns - The decoded token. | ||||||||||
| */ | ||||||||||
| export function verify(token: string, secretOrPublicKey: Secret, options?: VerifyOptions): object | string; | ||||||||||
| export function verify(token: string, secretOrPublicKey: Secret, options: VerifyOptions & { complete: true }): Jwt | string; | ||||||||||
| export function verify(token: string, secretOrPublicKey: Secret, options?: VerifyOptions): JwtPayload | string; | ||||||||||
|
|
||||||||||
| /** | ||||||||||
| * Asynchronously verify given token using a secret or a public key to get a decoded token | ||||||||||
|
|
@@ -193,6 +219,12 @@ export function verify( | |||||||||
| secretOrPublicKey: Secret | GetPublicKeyOrSecret, | ||||||||||
| callback?: VerifyCallback, | ||||||||||
| ): void; | ||||||||||
| export function verify( | ||||||||||
| token: string, | ||||||||||
| secretOrPublicKey: Secret | GetPublicKeyOrSecret, | ||||||||||
| options?: VerifyOptions & { complete: true }, | ||||||||||
| callback?: VerifyCallback<Jwt>, | ||||||||||
| ): void; | ||||||||||
| export function verify( | ||||||||||
| token: string, | ||||||||||
| secretOrPublicKey: Secret | GetPublicKeyOrSecret, | ||||||||||
|
|
@@ -206,5 +238,5 @@ export function verify( | |||||||||
| * [options] - Options for decoding | ||||||||||
| * returns - The decoded Token | ||||||||||
| */ | ||||||||||
| export function decode(token: string, options: DecodeOptions & { json: true } | DecodeOptions & { complete: true }): null | { [key: string]: any }; | ||||||||||
| export function decode(token: string, options?: DecodeOptions): null | { [key: string]: any } | string; | ||||||||||
| export function decode(token: string, options: DecodeOptions & { json: true } | DecodeOptions & { complete: true }): null | Jwt; | ||||||||||
| export function decode(token: string, options?: DecodeOptions): null | JwtPayload | string; | ||||||||||
|
Comment on lines
+241
to
+242
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps an optional type argument could be considered too?
Suggested change
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A type argument has come up before and shouldn't be added because of the following reason in the link you posted:
This is because otherwise you'll write code that assumes that all the tokens passed in are well formed which is bad since the tokens are usually passed from other systems or third parties... |
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this PR is months old now and has been approved and merged and published, but I just ran into a code breakage while upgrading
@types/jsonwebtokenfrom 8.5.1->8.5.5 which should be compatible.Given that:
JwtHeaderrequiresalgto be definedand that:
SignOptionsspecifies analgorithm?: Algorithm | undefined;and that:
jsonwebtoken's implementation of generating the header is:This leads to the
SignOptions.algorithmbeing completely ignored in 100% of usage.Separately, the Types have been broken in the interface for SignOptions.
Example code that used to work in 8.5.1 that broke in 8.5.2:
^ the above now fails type checking as
algis not defined in the header.The fix is pretty easy, move
algorithmintoheader.alg, but more so I just wanted to point out that these changes were not semantic version compatible and nowSignOptions.algorithmis completely ignored (due to the forcing of definingalgin the header).I'm happy to put up a PR if you want but I don't have strong opinions about what the right solution is,
eg: removing
SignOptions.algorithmor usingPartial<JwtHeader>in the SignOptions and correcting thejsonwebtokenpackage.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
algis a required attribute according to the rfcIf the changes were not versioned according to semantic versioning, then it must have been a mistake, not intentional.
I'm confused, is this
SignOptionsis inauth0/node-jsonwebtokenbecause that would be an implementation and surely this issue is on their side? I could be wrong, I would imagine the auth0 guys would know their stuff.For now I would assume that
SignOptionsneeds to be updated.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, it's how they implemented it.
I think there are a couple ambiguity problems-
jsonwebtokenproviding undocumented/unclear behavior when specifying algorithm (their README/Docs don't explain how it handles conflicts - eg ifSignOptions.algorithm = 'RS256'butSignOptions.header.alg = 'HS256') (seemingly accidentally)@types/jsonwebtokenintroducing a change that breaks existing implementations (see my case whereSignOptions.algorithmis defined butJwtHeader.algis not) since changing fromobjecttoJwtHeaderin theSignOptions.headertype, but only appears as a patch version8.5.1->8.5.2(also seemingly accidentally)My personal opinion is that there should only be 1 place to specify Algorithm. If I had my way, I'd agree with you to remove
algorithmfromSignOptions, fix thejsonwebtokenimplementation linked above, and keep it inJwtHeadersince it seems that is the least ambiguous path forward. That's a big change that affects both of these projects though, so I didn't put up a PR since that's just my opinion.For clarity: I perceived that both of these were just accidents, hopefully my tone didn't come off as negative or accusatory :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just got bitten by this. We had a package-lock file in place which was pulling in 8.5.1, so we didn't notice it until today when we finally updated the lock file. Thanks for this comment trail. It helped us understand the issue and implement a temporary fix.