markitosgv / JWTRefreshTokenBundle

Implements a Refresh Token system over Json Web Tokens in Symfony
MIT License
663 stars 158 forks source link

Question: Programatically creating a refresh token #270

Open joesaunderson opened 3 years ago

joesaunderson commented 3 years ago

Is it possible to programatically generate a refresh token? Similar to https://github.com/lexik/LexikJWTAuthenticationBundle/blob/2.x/Resources/doc/7-manual-token-creation.md

I want to handle the login / refresh option in GraphQL, so I want to generate the two tokens myself in a PHP resolver.

Or is there a better way of doing this?

joesaunderson commented 3 years ago

Think I have solved this with:

$refreshToken = $this->refreshTokenManager->createForUserWithTtl($user, 604800);

My next question, how do I implement a "manual" refresh in a resolver, and return the refreshed JWT

fd6130 commented 3 years ago

Think I have solved this with:

$refreshToken = $this->refreshTokenManager->createForUserWithTtl($user, 604800);

My next question, how do I implement a "manual" refresh in a resolver, and return the refreshed JWT

Not sure what do you mean by resolver, do you mean Symfony resolver or something else?

Perhaps you mean call something like /api/refresh api and pass it the refresh token, then the controller return a refreshed JWT?

I think you can do that by creating your own controller and logic.

joesaunderson commented 3 years ago

Not sure what do you mean by resolver, do you mean Symfony resolver or something else?

I am using GraphQL, which has the idea of Resolvers (essentially a Symfony controller). So my question is, how do I programatically do what the /api/refresh API was doing behind the scenes, if that makes sense?

fd6130 commented 3 years ago

Haven't learn about GraphQL yet. But for the /api/refresh, the logic is quite simple. You pass in the refresh token, check if the refresh token is exist in database and if it is still in fresh, generate a new jwt token and return it to the user.

For example in Symfony Controller:


/**
* @Route("/api/refresh")
*/
public function refreshJWT(Request $request)
{
   $refreshToken = $request->get('refresh_token');
   // check the database for the refresh token.
   // if exist and is still fresh, generate a new jwt token and return it.
   $jwt = // the generate jwt code ;
   return $this->json(['token' => $jwt]);
}
joesaunderson commented 3 years ago

Thanks for confirming that, makes sense to me now!

fd6130 commented 3 years ago

Thanks for confirming that, makes sense to me now!

It's been a while from this issue, I think it can be close now?

saifgo commented 2 years ago

I tried the solution provided by @joesaunderson but it didn't work and had to change it to this

use Gesdinet\JWTRefreshTokenBundle\Generator\RefreshTokenGeneratorInterface;
use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenManagerInterface;
private $RefreshTokenGenerator;
public function __construct(
        RefreshTokenGeneratorInterface $refreshTokenGenerator,
        RefreshTokenManagerInterface $refreshTokenManager) 
    {
        $this->refreshTokenGenerator = $refreshTokenGenerator;
        $this->refreshTokenManager = $refreshTokenManager;
    }

and when i want to create refresh token i do this

 $refreshToken = $this->refreshTokenGenerator->createForUserWithTtl($user, 604800);
 $this->refreshTokenManager->save($refreshToken);
 $refreshTokenString = $refreshToken->getRefreshToken();

after doing this the $refreshTokenString will be the refresh token and the refreshToken will be saved in the database for future use as @fd6130 cleared

MedDimessi commented 2 years ago

@fd6130 Can you please provider the 'use directory for the refreshTokenManager->createForUserWithTtl($user, 604800);, where does the function createForUserWithTtl() exist?? I'm using Symfony 5.3.

saifgo commented 2 years ago

@MedDimessi if you follow the code on my response you will know it cames from "refreshTokenGenerator" that you can use it with "Gesdinet\JWTRefreshTokenBundle\Generator\RefreshTokenGeneratorInterface;"

MedDimessi commented 2 years ago

@saifgo I did, but the JWTRefreshTokenBundle:0.12.0 deesn't have the Generator folder. That why I specified what version of Symfony I'm using.

I'm using Symfony 5.3.

orangevinz commented 2 years ago

@MedDimessi Same for me.. Did you find a solution ?

orangevinz commented 2 years ago

Ok I was not on the version 1.0 my bad

atanasov commented 2 years ago

If someone still needs this working on Symfony 5.3.* and "gesdinet/jwt-refresh-token-bundle": "^0.12"

use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenManagerInterface;
use Symfony\Component\PropertyAccess\PropertyAccessor;
    private function createRefreshToken(UserInterface $user)
    {
        $ttl = 2592000;
        $userIdentityField = 'username';
        $datetime = new \DateTime();
        $datetime->modify('+'.$ttl.' seconds');

        $refreshToken = $this->refreshTokenManager->create();

        $accessor = new PropertyAccessor();
        $userIdentityFieldValue = $accessor->getValue($user, $userIdentityField);

        $refreshToken->setUsername($userIdentityFieldValue);
        $refreshToken->setRefreshToken();
        $refreshToken->setValid($datetime);

        $this->refreshTokenManager->save($refreshToken);
        return $refreshToken->getRefreshToken();
    }