如何在Laravel应用程序中获取客户端ID?

时间:2017-10-30 22:00:09

标签: laravel laravel-passport

我已经设置了一个带有客户端身份验证的laravel应用程序。我发送了我的客户端ID和客户端密码,它给了我一个令牌。我可以登录我的laravel应用程序,但我无法弄清楚如何获取已获得授权的客户端的ID。

我已经看到使用auth()->user()->Token()->getAttribute('client_id')来获取客户端ID的提示,但由于我只使用客户端没有用户,因此尝试在空对象上调用Token()时出现错误。 Auth::id()也没有返回任何内容。我使用Request::header('Authorization')从标题中抓取了令牌,但它与数据库中的任何内容都不匹配。

2 个答案:

答案 0 :(得分:4)

我假设您正在使用客户端凭据授予令牌和CheckClientCredentials中间件。

您可以从持有人令牌中获取此信息,但这并不是那么简单。您需要使用令牌创建新的PSR7请求,并将其发送到oauth服务器以将其转换为可读数据。

这已在Passport提供的CheckClientCredentials中间件内完成。因此,一种方法是扩展CheckClientCredentials中间件,只需从中间件内部手动设置请求对象上的所需字段。

首先,创建app/Http/Middleware/MyCheckClientCredentials.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Auth\AuthenticationException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Laravel\Passport\Http\Middleware\CheckClientCredentials;

class MyCheckClientCredentials extends CheckClientCredentials
{
    /**
     * The Resource Server instance.
     *
     * @var \League\OAuth2\Server\ResourceServer
     */
    private $server;

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  mixed  ...$scopes
     * @return mixed
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function handle($request, Closure $next, ...$scopes)
    {
        $psr = (new DiactorosFactory)->createRequest($request);

        try {
            $psr = $this->server->validateAuthenticatedRequest($psr);

            // This is the custom line. Set an "oauth_client_id" field on the
            // request with the client id determined by the bearer token.
            $request['oauth_client_id'] = $psr->getAttribute('oauth_client_id');

        } catch (OAuthServerException $e) {
            throw new AuthenticationException;
        }

        $this->validateScopes($psr, $scopes);

        return $next($request);
    }
}

接下来,更新您的app/Http/Kernel.php以使用自定义中间件而不是Passport中间件中的内置版本:

protected $routeMiddleware = [
    'client' => \App\Http\Middleware\MyCheckClientCredentials::class,
];

正常将中间件应用到您的路线:

Route::get('/user', function(Request $request) {
    // Should show "oauth_client_id" field.
    dd($request->all());
})->middleware('client');

如果您不想在中间件中执行此操作,则可以研究Passport中间件的工作原理,并在某些类型的服务中重用此代码(如果您愿意)。

注意:所有未经测试。

答案 1 :(得分:0)

我必须在我的记录器中间件中做类似的事情:

.......................
    $user = $request->user();

    if($user) {
        // assume the authorization header exists, since the user is authenticated
        $header = $request->headers->get('authorization');

        if($header) { // authorization header is not set when testing via Passport::actingAs() 
            /**
             * Stolen from League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator#63 
             */

            // Get the actual jwt string from the header
            $jwt = trim(preg_replace('/^(?:\s+)?Bearer\s/', '', $header));

            // Parse the token from the string
            $token = (new Lcobucci\JWT\Parser())->parse($jwt);

            // Get the ID from the token
            $oauthClientId = $token->getClaim('aud');
        }
    }
.......................