如何向 laravel-passport 访问令牌添加自定义声明?

问题描述 投票:0回答:4

我刚刚使用了 laravel-passport,它与 jwt auth 相同。

我想向我的 accessToken 添加一些自定义声明,可以吗??

我想在访问令牌和 API 调用时传递

2fa_status => true
有了这个访问令牌,我也想要来自令牌的声明。

例如代币的预期索赔

{
  "aud": "7",
  "jti": "123",
  "iat": 1568368682,
  "nbf": 1568368682,
  "exp": 1599991082,
  "sub": "2",
  "scopes": [],
  "2fa_status": false
}

我正在生成如下令牌:

  $tokenResult = $user->createToken('Personal Access Token');
laravel laravel-passport
4个回答
1
投票

认为你可以做的事情与这个问题的答案非常相似: 自定义令牌响应 Laravel Passport

在您自己的 BearerTokenResponse 类中,重写generateHttpResponse方法,在其中您可以在将其转换为 JWT 之前向访问令牌添加任何内容:

    public function generateHttpResponse(ResponseInterface $response)
    {
        $expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp();

        // add custom claims here, ie. $this->accessToken->withClaim('name', 'value');

        $jwtAccessToken = $this->accessToken->convertToJWT($this->privateKey);

        ...

0
投票

我处于类似的情况,但我在身份验证过程中使用密码授予客户端向用户颁发令牌,并且我需要使用用户的个人访问令牌来生成自己的访问令牌以在第三方应用程序中使用。您可以通过更新范围来解决此问题。我还需要验证用户是否已通过 2fa。

在你的

AuthServiceProvider.php

    public function boot()
    {
        $this->registerPolicies();

        Passport::routes(function ($router) {
            $router->forAccessTokens();
            $router->forPersonalAccessTokens();
            $router->forTransientTokens(); // register the transient token. skip if all routes are enabled
        });

        // Add scope to verify the user
        // take note that here 2 scope for this due to refresh token scope
        Passport::tokensCan([
            '2fa-pass' => '2FA Pass',
            '2fa-not-pass' => '2FA Pass',
        ]);
    }

下一步是在身份验证过程中发送密码授予类型

  // I'm using route::dispatch to do a proxy request
  // you can use Guzzle if you want
  $request->request->add([
    'grant_type' => 'password',
    'client_id' => 'client-id',
     client_secret' => 'client-secret',
    'username' => $credentials['email'],
    'password' => $credentials['password'],
    'scope' => '2fa-not-pass 2fa-pass' // take note that I added the two scope here
  ]);

  $tokenRequest = Request::create('/oauth/token', 'POST');

  $response = \Route::dispatch($tokenRequest);

然后在您的 2FA 验证流程中


   // your process of verifying the 2FA code

   // after that you need to update the scope by doing a refresh token
   $request->request->add([
     'grant_type' => 'refresh_token',
     'refresh_token' => $request->input('refresh_token'),
     'client_id' => 'client-id',
     'client_secret' => 'client-secret',
     'scope' => '2fa-pass' // I removed the 2fa-not-pass in refreshing the token
    ]);

  $tokenRequest = Request::create('/oauth/token', 'POST');

  $response = \Route::dispatch($tokenRequest);

请注意范围,刷新令牌时,您只能获得与原始访问令牌相同或更窄的范围。如果您尝试获取原始访问令牌未提供的范围,您将收到错误。 - 帕特里克斯

在这里回答:https://stackoverflow.com/a/45856634/11537130

请注意,这将生成具有新范围的新令牌


0
投票

对于仍在寻找答案的人来说,这对我的 Laravel 9 和 Passport 11 有用。

您需要创建

CustomClaimsAccessTokenTrait.php
并在其中添加您的自定义声明:

<?php

namespace App\Services\Tokens;

use App\Models\User;
use Lcobucci\JWT\Token;
use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;

trait CustomClaimsAccessTokenTrait
{
    use AccessTokenTrait;

    /**
     * Generate a JWT from the access token
     *
     * @return Token
     */
    private function convertToJWT()
    {
        $this->initJwtConfiguration();

        return $this->jwtConfiguration->builder()
            ->permittedFor($this->getClient()->getIdentifier())
            ->identifiedBy($this->getIdentifier())
            ->issuedAt(new \DateTimeImmutable())
            ->canOnlyBeUsedAfter(new \DateTimeImmutable())
            ->expiresAt($this->getExpiryDateTime())
            ->relatedTo((string)$this->getUserIdentifier())
            ->withClaim('scopes', $this->getScopes())
            ->withClaim('custom', 'myCustomClaim') // your custom claim
            ->getToken($this->jwtConfiguration->signer(), $this->jwtConfiguration->signingKey());
    }

    /**
     * Generate a string representation from the access token
     */
    public function __toString()
    {
        return $this->convertToJWT()->toString();
    }
}

然后你必须创建使用我们的

CustomTokenAccess.php
CustomClaimsAccessTokenTrait

<?php

namespace App\Services\Tokens;

use Laravel\Passport\Bridge\AccessToken;

class CustomAccessToken extends AccessToken
{
    use CustomClaimsAccessTokenTrait;
}

现在你要做的就是告诉 Passport 使用我们的

CustomAccessToken
类作为
AccessToken
实体,所以在
AuthServiceProvider.php
中的
boot
方法中添加:

public function boot()
{
    // ...
    Passport::useAccessTokenEntity(CustomAccessToken::class);
}

现在,当您调试 JWT Token 时,结果如下:

{
  "aud": "7",
  "jti": "...",
  "iat": 1701432944.525137,
  "nbf": 1701432944.52514,
  "exp": 1701433244.452095,
  "sub": "139400",
  "scopes": [
    "patient-app"
  ],
  "custom": "myCustomClaim"
}

-1
投票

有可能

将此添加到

AuthServiceProvider

Passport::routes();
Passport::personalAccessClientId(1); //<-- this 1 is id of your personal key
Passport::tokensExpireIn(now()->addDays(15));
Passport::refreshTokensExpireIn(now()->addDays(30));

现在您可以像这样创建新令牌

$user->createToken('email')->accessToken; // you can change email to any for remember why this code generated like social facebook

根据文档添加更多参数尝试这个

$user->createToken('email', ['extra' => 'params'])->accessToken;

希望这有帮助

© www.soinside.com 2019 - 2024. All rights reserved.