-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add support for jwt #2946
Comments
Can I work on this feature? |
+1 |
So a JWT: JWT Is a JSON object with: Signature, Header and Payload. possibly this would be a nice feature: z.string().jwt({secret: process.env.MY_JWT_SECRET}, description: "this is a users JWT"})
.payload(z.object({...}); Resulting in a z.object with your defined properties, same functions like .safeParse, .parse, etc. Something like a Following example usage (what I think would be best) /**
* "sub": "1234567890",
* "name": "John Doe",
* "iat": 1516239022
*/
const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" // from JWT.io, no private info here.
const schema = z.string().jwt() // no secret, public JWT.
.payload(
z.object({
sub: z.string(),
name: z.string(),
iat: z.number()
})
); No Hope this helps in development! |
from https://datatracker.ietf.org/doc/html/rfc7519#section-2
Based on that, there is no real need for specifying that argument of const schema = z.string()
.jwt({
secret: process.env.MY_JWT_SECRET,
description: "this is a users JWT"
})
.withPayload({
sub: z.string(),
name: z.string(),
iat: z.number()
}); |
Maybe the `ignoreExpiration`: if `true` do not validate the expiration of the token. |
Agree with expire check false option, +1. Disagree with the Maybe it is a personal prefference, but I can safely say most devs prefer simple and conventions in naming, since zod is all about: .string .email .min .max .number .regex, it would not make sense to include with, instead just Let me know what you think! |
Agree with @m10rten Zod is a validation library and has nothing to do with Authorization/Authentication. |
Yess, focus should be on validating a valid JWT and get data from the payload. So plain and simple .jwt with return unknown or .payload; |
@m10rten
So in case you read Writing
One part of the token such as jose header very much affects other part of jwt token such as signature at the end. That's well beyond data encoding and data structure validation and should not be considered. And I'm not even telling you that JWTs can be validated by many libraries in JS, not only one. And if you decide to support signature validation you can't just force people to use specific library for their business validation like
You can't because it will force developers who use zod to use only specific set of supported encryption algorithms which is the main difference between those jwt libraries. The same as you can't decide to support every jwt library by forcing developers of zod to do so.
Also JWT by itself is not plain and simple and if you want plain and simple
|
Yess, so maybe its return type should be something like this: interface ReturnValue<ZodAny extends z.ZodTypeAny> {
headers: Record<HeaderTyped, string>;
signature: {
alg: string;
typ: "JWT"
};
payload: ZodAny;
}; Where a |
There are no methods in zod that change the type of what was passed to them. You change the type of value from string to object. {
"accessToken": "base64_of_json_of_jose_header.base64_of_json_of_payload.base64_of_binary_signature",
"refreshToken": "base64_of_json_of_jose_header.base64_of_json_of_payload.base64_of_binary_signature"
} And on the client after validation I may want to store it somewhere as is. As string. And I as a developer may choose to use any js library there is to validate the token (not only payload) using any algorithm implementation I want. Returning And by the way your |
Is it changing or validating. It is not transforming if you have jwt, else why would you event implement a .jwt method? |
It DOES transform from
|
I believe I am following you, but is this really an issue? Lets add an example: import { z } from "zod";
// both of these are on a string, check if its in a format, and then return that string.
const email = z.string().email();
// so .jwt follows the .email
const jwt = z.string().jwt();
// all you would do with a .payload is indeed a .transform with a lot of steps taken out.
const jwtWithPayloadSchema = z.string()
.jwt()
.payload(
z.object({...})
);
// so where .jwt should just check if it has these 3 elements: signature, headers and payload.
// the .payload adds a transform layer with a validation on the jwt data.
const userJwt = z.string()
.jwt()
.payload(
z.object({
userId: z.string(),
})
);
const parsed = userJwt.parse(unknownData);
// ^: {userId: string}, or if you want to also strip out the other parts: {signature: ..., headers: ..., payload: {userId: string}} I think this way can not hurt users in their way of using a JWT. |
2024 and still no jwt regex :(. |
@colinhacks Can we get your opinion on this? It seems jwt support would be very usefull (validating the format not the payload). |
Guys, I think validation of a I don't think Zod should be responsable for receiving and checking signature, expiration or anything else. Also for payload, for me, it just make sense to check after I already know the string is a valid Jwt (checked by zod), and has valid signature (checked by jose, jsonwebtoken...), then I would check payload, with another regular object zod schema. I believe that checking and returning the payload without checking the signature (and zod shouldn't check for signature), may lead to the use of this payload if it just respect the schema, what would be a safety fail. I already open a PR following this line in August, should I do anything else to make it merged? |
@danilomourelle Looks like you need to ping/contact @colinhacks or anyone else with merge privilege to merge your PR. |
Seems like a related PR for this was merged to |
Add support to verify jwt strings. For example
The text was updated successfully, but these errors were encountered: