Good morning! I have another API where I want to verify the user is a Payload user / has a session. Am I able to accomplish this using the request credentials of a signed in user?
So basically I'd send a request with credentials: true to my other API (non-payload)
I can see that a non-signed cookie is on the request
{
'payload-token': 'secret-token'
}
Can I then use my payload secret on the non-payload API to verify that is a valid user?
OK so I've opted to go with JWT
And I have the JWT on my other API and my payload secret
I setup a function to check the token before my API responds to requests
const verifyToken = (req: express.Request, res: express.Response): boolean => {
if (req.cookies["payload-token"]) {
console.log(req.cookies["payload-token"], process.env.PAYLOAD_SECRET);
try {
const decoded = jwt.verify(
req.cookies["payload-token"],
process.env.PAYLOAD_SECRET,
{
algorithms: ["HS256"],
}
);
console.log(decoded);
return true;
} catch (err) {
console.log("Invalid token request.", err);
return false;
}
} else {
console.log("Missing token in request.");
return false;
}
};
However, I keep getting
Invalid token request. JsonWebTokenError: invalid signature
@jmikrut Sorry for the ping, any idea on why the signature may have failed? I confirmed that both are passed to the verifyToken function and the secret is from my Payload env
What's even odder, is that the signature is valid when testing the combo on
https://jwt.io/
There will be another condition in the fn btw checking the result of decoded
But rn it throws each time
Things I have tried so far:
1.) Tried to base64 encode the payload secret.
2.) Tried to specify the correct algorithm
However, the result from jwt.io still says the signature is valid while jsonwebtoken reports the opposite
@jmikrut WOW 3 pings, i am so sorry, this is what I am stuck on
I can help here in a bit - wrapping up my meetings shortly
Ah thank you so much!
I think that the payload secret is NOT the signing key for the JWT
ok i am alive
so, i bet what your issue is, is that you need to hash your raw
secret
in the same way that Payload does internally:
https://github.com/payloadcms/payload/blob/master/src/payload.ts#L164
notice how we are taking whatever you provide as a secret string, hashing it, and then taking only the first 32 chars
then from there you should be able to verify the token in the same way that we do in our auth operations, for example, here:
https://github.com/payloadcms/payload/blob/master/src/auth/operations/refresh.ts#L60
Hey, following up, this worked perfectly!
amazing
@jmikrut One thing I should mention
The decoded JWT is an object with that you would expect (including the saveToJWT data)
But it seems to want a string or jwtpayload?
Do I need to make an interface for what I expect back?
Maybe I should be running jqt.verify, then jwt.decode, but it feels like an extra step / may not resolve the type issue
jwt.verify
returns the results of what you would send back with
decode
i believe
Anyway, not the hugest deal, but wanted to mention it
it just adds an extra step to verify the token
Hmmm the value I get back from the .verify is the object, maybe I'm doing something wrong
const decoded = jwt.verify(req.cookies["payload-token"], hash, {
algorithms: ["HS256"],
});
logging decoded =
{
email: 'cmcgrane@saa.com',
id: '63b84be941b40f6bd0a5899b',
collection: 'users',
repid: '229784',
iat: 1679420667,
exp: 1679427867
}
that looks like what i would expect
hmm
It expects decoded to be
string | JwtPayload
oh maybe JwtPayload is the object, it just wouldn't know of any props on it
In any case, not sure if this is good practice but
interface jwtResponse {
email: string,
id: string,
collection: string,
repid: string,
iat: number,
exp: number
}
const decoded = jwt.verify(req.cookies["payload-token"], hash, {
algorithms: ["HS256"],
});
const {repid} = (decoded as jwtResponse)
😅
I feel bad because I never post easy questions
i'd just say
if (typeof decoded !== 'string')
i'm not sure why that library could send back a string, maybe in the case of an error - - or maybe the contents of the token in the first place could be a string, in which point, by verifying, it would send
backa string
generally you should avoid using
as
and instead verify / narrow types manually
Thank you, will do!!
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.