Laravel Passport,通过密码客户端

时间:2016-09-13 10:17:38

标签: laravel

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

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

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

我问,因为我每次向POST /oauth/token提出请求时,都是password_clientaccess_token请求user password_client { {1}}获取revoked

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

我错过了什么吗?

3 个答案:

答案 0 :(得分:3)

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

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

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

应用程序/提供者/ 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();
    }
}

应用程序/听众/ 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();
    }
}

答案 1 :(得分:2)

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

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 :(得分:0)

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

use Dusterio\LumenPassport\LumenPassport;

public function boot()
{
        $this->setPassportConfiguration();
}

private function setPassportConfiguration(): void
{
        LumenPassport::allowMultipleTokens();
}