Passport: Get a PersonalAccessTokenResult object from an existing access_token

Created on 26 Jul 2018  ·  8Comments  ·  Source: laravel/passport

Is there a way to get a PersonalAccessTokenResult -especially the JWT- from an existing access_token? I'd like to avoid generating every time a token, and return the JWT from the access_token of the user, in the DB.

This is because I have a small part of my app built with VueJS, and I'd like to make some API calls.

Thanks!

Most helpful comment

Here is a solution I coded to generate JWT access token from retrieved model from oauth_access_tokens:

<?php

namespace App\Models;

use Laravel\Passport\Passport;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use League\OAuth2\Server\CryptKey;

class AccessToken extends \Laravel\Passport\Token
{
    /**
     * Generate a JWT from the access token
     *
     * @return string
     */
    public function convertToJWT()
    {
        $privateKey = new CryptKey(
            'file://' . Passport::keyPath('oauth-private.key'),
            null,
            false
        );

        return (string) (new Builder())
            ->setAudience($this->client_id)
            ->setId($this->id, true)
            ->setIssuedAt(time())
            ->setNotBefore(time())
            ->setExpiration($this->expires_at->getTimestamp())
            ->setSubject($this->user->id)
            ->set('scopes', [])
            ->sign(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase()))
            ->getToken();
    }
}

Then just use

$token = AccessToken::where('user_id', 1)->where('expires_at', '>', Carbon::now())
            ->orderBy('created_at', 'desc')->first();

$token->convertToJWT();

All 8 comments

Personal access tokens are long lived tokens.
They are better suited for people implementing something on your API.
If you're consuming your own API then you should use a password grant token. See more: https://laravel.com/docs/5.6/passport#password-grant-tokens

I'm also interested in how I can generate access token from existing database record.

Here is a solution I coded to generate JWT access token from retrieved model from oauth_access_tokens:

<?php

namespace App\Models;

use Laravel\Passport\Passport;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use League\OAuth2\Server\CryptKey;

class AccessToken extends \Laravel\Passport\Token
{
    /**
     * Generate a JWT from the access token
     *
     * @return string
     */
    public function convertToJWT()
    {
        $privateKey = new CryptKey(
            'file://' . Passport::keyPath('oauth-private.key'),
            null,
            false
        );

        return (string) (new Builder())
            ->setAudience($this->client_id)
            ->setId($this->id, true)
            ->setIssuedAt(time())
            ->setNotBefore(time())
            ->setExpiration($this->expires_at->getTimestamp())
            ->setSubject($this->user->id)
            ->set('scopes', [])
            ->sign(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase()))
            ->getToken();
    }
}

Then just use

$token = AccessToken::where('user_id', 1)->where('expires_at', '>', Carbon::now())
            ->orderBy('created_at', 'desc')->first();

$token->convertToJWT();

Hi there,

Looks like this is a question which can be asked on a support channel. Please only use this issue tracker for reporting bugs or problems. If you have a question on how to use functionality provided by this repo you can try one of the following websites:

I think you have a look at https://laravel.com/docs/5.6/passport#consuming-your-api-with-javascript

Here is a solution I coded to generate JWT access token from retrieved model from oauth_access_tokens:

<?php

namespace App\Models;

use Laravel\Passport\Passport;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Key;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use League\OAuth2\Server\CryptKey;

class AccessToken extends \Laravel\Passport\Token
{
    /**
     * Generate a JWT from the access token
     *
     * @return string
     */
    public function convertToJWT()
    {
        $privateKey = new CryptKey(
            'file://' . Passport::keyPath('oauth-private.key'),
            null,
            false
        );

        return (string) (new Builder())
            ->setAudience($this->client_id)
            ->setId($this->id, true)
            ->setIssuedAt(time())
            ->setNotBefore(time())
            ->setExpiration($this->expires_at->getTimestamp())
            ->setSubject($this->user->id)
            ->set('scopes', [])
            ->sign(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase()))
            ->getToken();
    }
}

Then just use

$token = AccessToken::where('user_id', 1)->where('expires_at', '>', Carbon::now())
            ->orderBy('created_at', 'desc')->first();

$token->convertToJWT();

This no longer works on the latest Laravel and lcobucci/jwt. Do you have an updated solution?

@bkintanar Don't have any thought about this, that project is not updated yet, works with older Laravel.

@vedmant no worries. I manage to work on it with your example. Here's my take on it. Thank you for your help.

<?php

namespace App\Eloquent\Passport;

use DateTimeImmutable;
use Laravel\Passport\Passport;
use Lcobucci\JWT\Configuration;
use League\OAuth2\Server\CryptKey;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
use Laravel\Passport\PersonalAccessTokenResult;

class Token extends \Laravel\Passport\Token
{
    public function getPersonalAccessTokenResult()
    {
        $privateKey = new CryptKey(
            'file://' . Passport::keyPath('oauth-private.key'),
            null,
            false
        );

        $configuration = Configuration::forSymmetricSigner(
            new Sha256(),
            InMemory::file($privateKey->getKeyPath()),
        );

        $now = new DateTimeImmutable();
        $expiresAt = new DateTimeImmutable($this->expires_at->toDateTimeString());

        $token = $configuration->builder()
            ->permittedFor($this->client_id)
            ->issuedBy('self')
            ->identifiedBy($this->id)
            ->issuedAt($now)
            ->canOnlyBeUsedAfter($now)
            ->expiresAt($expiresAt)
            ->relatedTo($this->user->id)
            ->withClaim('scopes', [])
            ->getToken($configuration->signer(), $configuration->signingKey());

        return new PersonalAccessTokenResult($token->toString(), $this);
    }
}

My approach returns a PersonalAccessTokenResult vs String on your implementation since it's what I needed on my app.

Here's how I apply it.

if (! $token = $user->tokens->where('revoked', false)->where('expires_at', '>', Carbon::now())->first()) {
    $token = $user->createToken('App');
}

$this->tokenResult = $token->getPersonalAccessTokenResult();
Was this page helpful?
0 / 5 - 0 ratings