【问题标题】:Laravel Passport, multiple connexions via password clientLaravel Passport,通过密码客户端进行多重连接
【发布时间】:2017-01-20 21:49:54
【问题描述】:

我无法理解如何使用 Laravel Passport 通过密码客户端为同一用户实现多个连接:

我有一个移动应用程序,它需要与基于 Laravel 的 API 进行通信。我的用户在首次启动应用程序时必须输入他们的loginpassword 才能获得access_token

所以我认为我需要将我的密码客户端secret 放入我的移动应用程序的代码中才能请求令牌。但是,如果我的用户有一部 iPhone 和一部 iPad,并且他想从两者登录,该怎么办。

我之所以问是因为每次我从同一个password_clientPOST /oauth/token 发出请求时,使用我的password_client 请求的某个user 的每个access_token 都会得到revoked

这是否意味着,每次我的用户使用他的 iPad 时,他都会与他的 iPhone 断开连接,因为令牌不再有效?

我错过了什么吗?

【问题讨论】:

    标签: laravel


    【解决方案1】:

    您可以编写自己的控制器和路由...

    Passport 有一个定义的“Laravel\Passport\Http\Controllers\AccessTokenController”,并且有一个名为“issueToken()”的方法。

    如果您看到下面的方法,它会调用函数“revokeOtherAccessTokens()”,而这删除撤销所有“access_tokens”使用“Laravel\Passport\TokenRepository”

    所以你可以做的是编写你自己的控制器并防止调用“revokeOtherAccessTokens()”

    您必须记住的事实是,访问令牌永远不会被修剪或撤销,至少在刷新令牌已发布或手动删除它们时。

    刷新令牌和访问令牌在发出刷新令牌时被撤销,因为方法“respondToAccessTokenRequest()”中的“League\OAuth2\Server\Grant\RefreshTokenGrant”已经撤销了旧的“access_token”和“refresh_token”,所以在这种情况下,我们不必担心撤销或删除它们。

    ...
    // Expire old tokens
    $this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']);
    $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']);
    ...
    

    这是一个示例实现,希望对您有所帮助:

    路线:

    Route::post('oauth/access_token', 'Auth\OAuth2Controller@issueToken');
    

    自定义控制器:

    <?php
    
    namespace App\Http\Controllers\Auth;
    
    use Laravel\Passport\Http\Controllers\HandlesOAuthErrors;
    
    use Zend\Diactoros\Response as Psr7Response;
    use Psr\Http\Message\ServerRequestInterface;
    use League\OAuth2\Server\AuthorizationServer;
    
    use App\Http\Controllers\Controller;
    
    class OAuth2Controller extends Controller
    {
        use HandlesOAuthErrors;
    
        /**
         * The authorization server.
         *
         * @var AuthorizationServer
         */
        protected $server;
    
        /**
         * Create a new controller instance.
         *
         * @param  AuthorizationServer  $server
         * @return void
         */
        public function __construct(AuthorizationServer $server)
        {
            $this->server = $server;
        }
    
        /**
         * Authorize a client to access the user's account.
         *
         * @param  ServerRequestInterface  $request
         * @return Response
         */
        public function issueToken(ServerRequestInterface $request)
        {
            return $this->withErrorHandling(function () use ($request) {
                return $this->server->respondToAccessTokenRequest($request, new Psr7Response);
            });
        }
    }
    

    【讨论】:

      【解决方案2】:

      我相信 Passport 改变了它处理访问令牌创建的方式,AccessTokenController 中的 @issueToken 方法不再撤销旧令牌(检查 Multiple Access Token)。

      我认为此更改是在@jesús-lozano-m 回答之前引入的,因此不再需要自定义控制器。

      但是,如果您想撤销旧令牌,现在您可以通过设置 Passport 事件 AccessTokenCreated 的侦听器来实现。

      app/Providers/eventServiceProvider.php:

      <?php
      
      namespace App\Providers;
      
      use Illuminate\Support\Facades\Event;
      use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
      
      class EventServiceProvider extends ServiceProvider {
          protected $listen = [
              'Laravel\Passport\Events\AccessTokenCreated' => [
                  'App\Listeners\RevokeOldTokens'
              ]
          ];
          public function boot() {
              parent::boot();
          }
      }
      

      app/Listeners/RevokeOldTokens.php:

      <?php
      
      namespace App\Listeners;
      
      use Laravel\Passport\Events\AccessTokenCreated;
      use Laravel\Passport\Client;
      use Carbon\Carbon;
      
      class RevokeOldTokens {
          public function __construct() {
              //
          }
          public function handle(AccessTokenCreated $event) {
              $client = Client::find($event->clientId);
              // delete this client tokens created before one day ago:
              $client->tokens()
                        ->where('user_id', $event->userId)
                        ->where('created_at', '<', Carbon::now()->subDay())
                        ->delete();
          }
      }
      

      【讨论】:

      • 谢谢。如何在 Lumen 框架中做到这一点?它在 \Laravel\Passport\Client 中没有“查找”方法
      【解决方案3】:

      我在下面提到我的 app/Providers/AuthServiceProvider 中的代码及其工作。它不会删除旧令牌并允许我从多个设备登录

      use Dusterio\LumenPassport\LumenPassport;
      
      public function boot()
      {
              $this->setPassportConfiguration();
      }
      
      private function setPassportConfiguration(): void
      {
              LumenPassport::allowMultipleTokens();
      }
      

      【讨论】:

        猜你喜欢
        • 2018-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-14
        • 2017-02-19
        • 2019-04-17
        • 2019-07-21
        相关资源
        最近更新 更多