#Can I parse the Payload cookie from another API?

54 messages · Page 1 of 1 (latest)

true shadow
#

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?

true shadow
#

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?

true shadow
#

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

#

@somber dawn 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/

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

#

There will be another condition in the fn btw checking the result of decoded

#

But rn it throws each time

true shadow
#

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

true shadow
#

@somber dawn WOW 3 pings, i am so sorry, this is what I am stuck on

somber dawn
#

I can help here in a bit - wrapping up my meetings shortly

true shadow
#

Ah thank you so much!

#

I think that the payload secret is NOT the signing key for the JWT

somber dawn
#

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:

#

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:

true shadow
#

Hey, following up, this worked perfectly!

somber dawn
#

amazing

true shadow
#

@somber dawn 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

somber dawn
#

jwt.verify returns the results of what you would send back with decode i believe

true shadow
#

Anyway, not the hugest deal, but wanted to mention it

somber dawn
#

it just adds an extra step to verify the token

true shadow
#

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
}
somber dawn
#

that looks like what i would expect

true shadow
#

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

somber dawn
#

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 back a string

#

generally you should avoid using as and instead verify / narrow types manually