简体   繁体   English

Laravel Passport:如何从 Bearer Token 获取访问令牌

[英]Laravel Passport: How do i get Access token from Bearer Token

I requested client_credentials like below:我要求如下 client_credentials:

{
    "grant_type": "client_credentials",
    "client_id": 8,
    "client_secret": "XXNKXXqJjfzG8XXSvXX1Q4pxxnkXmp8tT8TXXKXX",
    "redirect_uri": "",
    "scope": "*"
}

And then received response below:然后收到以下回复:

{
    "token_type": "Bearer",
    "expires_in": 31536000,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGcXXXJSUzI1NiIsImp0aSI6ImEzYjJhZmU5OTYzMTE5MDAyZDAwZmEzNzU0ZGY3ZTRkMTgwYzhlYWRmNGQyOGU5MTI4YjAyYjJmYWQxZjY1NjUzMzAyZjNlZTI4MTgxMDFhIn0.eyJhdWQiOiI4IiwianRpIjoiYTNiMmFmZTk5NjMxMTkwMDJkMXXXYTM3XXXkZjdlNGQxODBjOGVhZGY0ZDI4ZTkxMjhiMDJiMmZhZDFmNjU2NTMzMDJmM2VlMjgxODEwMWEiLCJpYXQiOjE1NDAwMTQxNTUsIm5iZiI6MTU0MDAxNDE1NSwiZXhwIjoxNTcxNTUwMTU1LCJzdWIiOiIiLCJzY29wZXMiOltdfQ.sNSYywfBf27yAojqZclpjliysbQARlYFktzanTMecXXXIai5DgJY0sKhGpHktP5cqirYdemoFKy2nOxzZ8g29gCQQ63zmxe3vpbDz1GAdrjCDWoUlwSXXXHx4VIsdSIzVdi9XyvPKaLKMdoL6nFeWgpgXKGIvHKdiHjKgQbY_08Qa6JMN5Up27qmIOQoXJNAf1nuXvBMabUU_Js7VNspwPfdC8nMZ5zhK1A_c32_lDRtHqkhDfqqBXdUB-inx-zixhn2ODC4b4tkdj7XXXXlVKFxHxKM3aVOMFlmKhypSDwIUB0dPsN8iHcLzkl1yjzRQcOvQEj5BXWLkLCPdkiX2YJuFiWGUm_nxiYoIRV3ptJDeBI5OJI870JTOwBfJePrHTbXmhbjNSQSflLtiOV34wbPQZWH3KMKcsGVYvXXX3rcO5cbZWeeJLGPPYYO-_AWDmdAm-Qsb6Tw1sPxEZRw0dw3zBHnLVrEK9GXXXN2U5wE9Ka3id8ecOJSXSD39X1PyZUB9dJTidmbiWYWgskSTsqLuWfzXXXtlXkb1iOO37kT_Y5zr71Wp1RJ1Fp38yIyHI6fR9hKqeNALSqhv2ALmcSMQsFGTtPG98lGulu-vRJJhgMJ3C3fSTljN7o9BM7Jz-h0ymxC8sSMSNsXakK1qu40vD40zRJMB09sBPjIAVo"
}

In database, it will create record in oauth_access_tokens table, as follow:在数据库中,它将在oauth_access_tokens表中创建记录,如下所示:

id: 53ad95f4438e0f30769fa7e642e9c5b2fbd994fb3a95ece4a86578b07d2d72e61c01301df37e9bdb
user_id: NULL
client_id: 8
name: NULL
scopes: []
revoked: 0
created_at: 2021-11-05 09:30:14
updated_at: 2021-11-05 09:30:14
expires_at: 2021-11-05 09:30:14

Then I will use the access_token given above to consume my API by sending request Header as follow:然后我将使用上面给出的access_token通过发送请求 Header 来使用我的 API,如下所示:

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGcXXXJSUzI1NiIsImp0aSI6ImEzYjJhZmU5OTYzMTE5MDAyZDAwZmEzNzU0ZGY3ZTRkMTgwYzhlYWRmNGQyOGU5MTI4YjAyYjJmYWQxZjY1NjUzMzAyZjNlZTI4MTgxMDFhIn0.eyJhdWQiOiI4IiwianRpIjoiYTNiMmFmZTk5NjMxMTkwMDJkMXXXYTM3XXXkZjdlNGQxODBjOGVhZGY0ZDI4ZTkxMjhiMDJiMmZhZDFmNjU2NTMzMDJmM2VlMjgxODEwMWEiLCJpYXQiOjE1NDAwMTQxNTUsIm5iZiI6MTU0MDAxNDE1NSwiZXhwIjoxNTcxNTUwMTU1LCJzdWIiOiIiLCJzY29wZXMiOltdfQ.sNSYywfBf27yAojqZclpjliysbQARlYFktzanTMecXXXIai5DgJY0sKhGpHktP5cqirYdemoFKy2nOxzZ8g29gCQQ63zmxe3vpbDz1GAdrjCDWoUlwSXXXHx4VIsdSIzVdi9XyvPKaLKMdoL6nFeWgpgXKGIvHKdiHjKgQbY_08Qa6JMN5Up27qmIOQoXJNAf1nuXvBMabUU_Js7VNspwPfdC8nMZ5zhK1A_c32_lDRtHqkhDfqqBXdUB-inx-zixhn2ODC4b4tkdj7XXXXlVKFxHxKM3aVOMFlmKhypSDwIUB0dPsN8iHcLzkl1yjzRQcOvQEj5BXWLkLCPdkiX2YJuFiWGUm_nxiYoIRV3ptJDeBI5OJI870JTOwBfJePrHTbXmhbjNSQSflLtiOV34wbPQZWH3KMKcsGVYvXXX3rcO5cbZWeeJLGPPYYO-_AWDmdAm-Qsb6Tw1sPxEZRw0dw3zBHnLVrEK9GXXXN2U5wE9Ka3id8ecOJSXSD39X1PyZUB9dJTidmbiWYWgskSTsqLuWfzXXXtlXkb1iOO37kT_Y5zr71Wp1RJ1Fp38yIyHI6fR9hKqeNALSqhv2ALmcSMQsFGTtPG98lGulu-vRJJhgMJ3C3fSTljN7o9BM7Jz-h0ymxC8sSMSNsXakK1qu40vD40zRJMB09sBPjIAVo

question: how do I'm able to get oauth_access_tokens column id in my controller based on Bearer token given to my server?问题:如何根据提供给我的服务器的 Bearer 令牌在我的控制器中获取oauth_access_tokensid

EX: how do I get this value in my controller: EX:如何在我的控制器中获取此值:

53ad95f4438e0f30769fa7e642e9c5b2fbd994fb3a95ece4a86578b07d2d72e61c01301df37e9bdb

Based on Bearer token given below:基于下面给出的 Bearer 令牌:

Bearer eyJ0eXAiOiJKV1QiLCJhbGcXXXJSUzI1NiIsImp0aSI6ImEzYjJhZmU5OTYzMTE5MDAyZDAwZmEzNzU0ZGY3ZTRkMTgwYzhlYWRmNGQyOGU5MTI4YjAyYjJmYWQxZjY1NjUzMzAyZjNlZTI4MTgxMDFhIn0.eyJhdWQiOiI4IiwianRpIjoiYTNiMmFmZTk5NjMxMTkwMDJkMXXXYTM3XXXkZjdlNGQxODBjOGVhZGY0ZDI4ZTkxMjhiMDJiMmZhZDFmNjU2NTMzMDJmM2VlMjgxODEwMWEiLCJpYXQiOjE1NDAwMTQxNTUsIm5iZiI6MTU0MDAxNDE1NSwiZXhwIjoxNTcxNTUwMTU1LCJzdWIiOiIiLCJzY29wZXMiOltdfQ.sNSYywfBf27yAojqZclpjliysbQARlYFktzanTMecXXXIai5DgJY0sKhGpHktP5cqirYdemoFKy2nOxzZ8g29gCQQ63zmxe3vpbDz1GAdrjCDWoUlwSXXXHx4VIsdSIzVdi9XyvPKaLKMdoL6nFeWgpgXKGIvHKdiHjKgQbY_08Qa6JMN5Up27qmIOQoXJNAf1nuXvBMabUU_Js7VNspwPfdC8nMZ5zhK1A_c32_lDRtHqkhDfqqBXdUB-inx-zixhn2ODC4b4tkdj7XXXXlVKFxHxKM3aVOMFlmKhypSDwIUB0dPsN8iHcLzkl1yjzRQcOvQEj5BXWLkLCPdkiX2YJuFiWGUm_nxiYoIRV3ptJDeBI5OJI870JTOwBfJePrHTbXmhbjNSQSflLtiOV34wbPQZWH3KMKcsGVYvXXX3rcO5cbZWeeJLGPPYYO-_AWDmdAm-Qsb6Tw1sPxEZRw0dw3zBHnLVrEK9GXXXN2U5wE9Ka3id8ecOJSXSD39X1PyZUB9dJTidmbiWYWgskSTsqLuWfzXXXtlXkb1iOO37kT_Y5zr71Wp1RJ1Fp38yIyHI6fR9hKqeNALSqhv2ALmcSMQsFGTtPG98lGulu-vRJJhgMJ3C3fSTljN7o9BM7Jz-h0ymxC8sSMSNsXakK1qu40vD40zRJMB09sBPjIAVo

To get the user by the token, you need to understand what the token is.要通过令牌获取用户,您需要了解令牌是什么。

The token is broken up into three base64 encoded parts: the header, the payload, and the signature, separated by periods.令牌分为三个 base64 编码部分:标头、有效负载和签名,以句点分隔。 In your case, since you're just wanting to find the user, you just need the header在你的情况下,因为你只是想找到用户,你只需要标题

To get the header, you can do something like this:要获取标题,您可以执行以下操作:

$access_token = "eyJ0eXAiOiJKV1QiLCJhbGcXXXJSUzI......"

// break up the string to extract only the token

$auth_header = explode(' ', $access_token);
$token = $auth_header[1];

// break up the token into its three respective parts
$token_parts = explode('.', $token);
$token_header = $token_parts[0];

// base64 decode to get a json string
$token_header_json = base64_decode($token_header);
// you'll get this with the provided token:



{"typ":"JWT","alg":"RS256","jti":"9fdb0dc4382f2833ce2d3993c670fafb5a7e7b88ada85f490abb90ac211802720a0fc7392c3f2e7c"}

// then convert the json to an array
$token_header_array = json_decode($token_header_json, true);

Once you have this, you can find the user's token in the jti key:一旦你有了这个,你可以在 jti 密钥中找到用户的令牌:

$user_token = $token_header_array['jti'];

I learnt this from @samsquanch我从@samsquanch 学到的

*if you guys got any better solution let me know... *如果你们有更好的解决方案,请告诉我...

so far, this is how i kill it:到目前为止,这就是我杀死它的方式:

  1. I Overriding CheckClientCredentials middleware:我覆盖CheckClientCredentials中间件:

     use Laravel\Passport\Http\Middleware\CheckClientCredentials as Middleware; class CheckClientCredentials extends Middleware{ public function handle($request, Closure $next, ...$scopes){ $psr = (new DiactorosFactory)->createRequest($request); try { $psr = $this->server->validateAuthenticatedRequest($psr); } catch (OAuthServerException $e) { throw new AuthenticationException; } $this->validateScopes($psr, $scopes); $request->attributes->set('oauth_access_token_id', $psr->getAttribute('oauth_access_token_id')); $request->attributes->set('oauth_client_id', $psr->getAttribute('oauth_client_id')); $request->attributes->set('oauth_user_id', $psr->getAttribute('oauth_user_id')); $request->attributes->set('oauth_scopes', $psr->getAttribute('oauth_scopes')); return $next($request); }

    } }

  2. access it in controller:在控制器中访问它:

     dd($request->get('oauth_access_token_id'));

For Laravel 8, perhaps others.对于 Laravel 8,也许还有其他。

I created a middleware based on the logic of League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator我根据League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator的逻辑创建了一个中间件

I added it to app/Http/Kernel.php in the api section of $middlewareGroups so that it runs for every api route.我将它添加到$middlewareGroupsapi部分的app/Http/Kernel.php中,以便它为每个api路由运行。

Here are the contents.以下是内容。 I'm not discounting other solutions - this is just the route I decided to go so thought I'd volunteer the class.我并没有忽视其他解决方案——这只是我决定走的路线,所以我想我会自愿参加这门课。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Encoding\CannotDecodeContent;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Token\InvalidTokenStructure;
use Lcobucci\JWT\Token\UnsupportedHeaderFound;

class MergeOauthIntoRequestAttributes
{
    /**
     * Handle an incoming request.
     *
     * @param Request $request
     * @param Closure $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // If authenticated and is an API endpoint and has the authorization header
        if($request->user() && $request->wantsJson() && $request->hasHeader('authorization')){

            $header = $request->header('authorization');

            $arrHdr = explode(' ', $header);
            if(count($arrHdr) >= 2){
                $jwt = $arrHdr[1];
            }else{
                $sErr = 'InjectOAuthDetailsIntoRequest - authorization header format not recognized.';
                logERR($sErr);
                $request->merge(['oauth'=>['s_error' => $sErr]]);
                return $next($request);
            }

            try {
                $jwtConfig = Configuration::forSymmetricSigner(
                    new Sha256(),
                    InMemory::plainText('')
                );

                // Attempt to parse the JWT
                $token = $jwtConfig->parser()->parse($jwt);

            } catch (CannotDecodeContent | InvalidTokenStructure | UnsupportedHeaderFound $exception) {
                logERR($exception->getMessage());
                $request->merge(['oauth'=>['s_error' => $exception->getMessage()]]);
                return $next($request);
            }

            $claims = $token->claims();
            $request->merge(['oauth'=>[
                'access_token_id' => $claims->get('jti')
                ,'client_id' => $this->convertSingleRecordAudToString($claims->get('aud'))
                ,'scopes' => $claims->get('scopes')
            ]]);
        }

        return $next($request);
    }

    /**
     * Convert single record arrays into strings to ensure backwards compatibility between v4 and v3.x of lcobucci/jwt
     *
     * @param mixed $aud
     *
     * @return array|string
     */
    private function convertSingleRecordAudToString($aud)
    {
        return \is_array($aud) && \count($aud) === 1 ? $aud[0] : $aud;
    }

}

The calls to logERR can be deleted or replaced with your own logging mechanism.logERR的调用可以删除或替换为您自己的日志记录机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM