我很难理解如何通过Laravel Passport的密码客户端为同一用户实现多个连接:
我有一个移动应用,需要与基于Laravel的API进行通信。我的用户在首次启动应用时,必须输入login
和password
才能获得access_token
。
所以我认为我需要将我的密码客户端secret
放入我的移动应用程序的代码中才能请求令牌。但是,如果我的用户有iPhone和iPad,他想从两者登录。
我问,因为我每次向POST /oauth/token
提出请求时,都是password_client
,access_token
请求user
password_client
{ {1}}获取revoked
。
这意味着,每次我的用户使用他的iPad时,他都会与iPhone断开连接,因为令牌不再有效?
我错过了什么吗?
答案 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();
}