Search code examples
phplaravellaravel-passportjwe

Is there a way to Asymmetrically encrypt access tokens created with Laravel Passport?


I am building an application which consists of 3 server. The first is my Authorization server, the second is my Database server(API) and finally my front-end server. I want to use asymmetrical encryption to encrypt the access token generated by my Authorization server so that sensitive data is not compromised and also so that i can send it along to my API and verify that the user making a request is actually who they claim to be. Is there anything in Laravel Passport that will make this implementation possible or is it better to use a third party library like PASETO or PHP JWT Framework??

Currently when i make a request to the Api

  1. The Api makes a call to the Authorization server to validate user using the access token.
  2. The Auth server validates the User
  3. If user validates, Api delivers the resources we asked for, else it return a validation error.

What i want to achieve with the Asymmetrical encryption is to eliminate the call to my Auth server before every request to the API and i read that i can achieve this using asymmetrical encryption.


Solution

  • To solve my problem I ended up using the SimpleJWT library to encrypt the data in the access token. The data is encrypted in the JWE claims.

      $headers = ['alg' => 'RSA-OAEP-256', 'enc' => 'A128CBC-HS256'];
      $access_token = {"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
      // Creating JWE object with headers and claims
      $jwe = new \SimpleJWT\JWE($headers, $claims);
      $jwe_encrypted = $jwe->encrypt($foreing_server_public_key);
    

    I later decrypt the token using the python library JWCrypto. I am thinking about making the switch to Authlib JOSE Guide because it seems to have a broader community and support.

    //Decrypting JWE
    //Private key should be key pair of public key used to encrypt token
    jwetoken.deserialize(jwe_encrypted, key=private_key)
    //Validating Signature since passport signs tokens when generating them
    jwstoken.verify(auth_public_key)
    //Payload should contain encrypted data
    data = json.loads(jwstoken.payload.decode())
    >> {"sub": "1234567890", "name": "John Doe", "iat": 1516239022}