auth2.0整个流程图如下
同步更新与我的主页
http://www.heibaiketang.com/blog/show/114.html
之前写过的相关文章
https://www.jianshu.com/p/357166e0138f
https://www.jianshu.com/p/3df8b2b6d533
https://www.jianshu.com/p/5cc70161e251
我们假设一个客户,服务端假设用腾讯的。
客户需要QQ登录授权操作。
1.它要向腾讯申请授权密钥和id
2.腾讯审核认证通过后,返回给app_id,app_key
3.客户把app_id,app_key给到自己的网站后台,
4.用户a在登录的时候选择QQ登录,这个时候,客户的网站会组织好请求参数,向腾讯发起授权登录请求,腾讯会判断用户是否登录,然后再下一步操作
5.腾讯收到授权登录请求之后,它会进行核对,是否放行,然后经过一些列通过之后,返回code给到商户
6.商户收到code,发起获取用户信息,
7.腾讯通过code确认认证之后,返回给相应的权限信息
8.客户网站收到返回的信息,进行本地会员进行登录操作。
这个就是典型的流程操作。
这个时候,我们可以规划出表有几个了
服务器端:必须有商户表,也就是客户端表,
laravel passport的对应表是
oauth_clients
认证客户端
商户发起请求之后,他会有个认证授权的认证码表,
oauth_auth_codes
认证code表
后来商户再次发起获得用户相关权限信息,这个时候,服务端需要分配token值,那么这个时候,就需要一个token存储表
oauth_access_tokens
通过认证token表,这个授权token表,他也会有过期时间,过期了,我们需要发起刷新token,那么我们就需要一个刷新token表
oauth_refresh_tokens
刷新token表
这里4个表就可以完成一套auth2.0的授权操作了。
那么laravel passport它还有一个表
oauth_personal_access_clients
个人授权客户端
这里只是记录了私人客户端的记录表,只是记录而已
这个我之前分享过,可我那个时候没去管实际用途场景
那么我们平台使用的场景到底如何呢?
假设我现在后台,我需要给小程序A一个接口分配一个密钥对,支付宝小程序一个密钥对,或者是我给第三方接入我们的数据密钥对,那么我们现在就可以用laravel passport来做了
1.第一个后台创建客户端,比如给小程序用的,支付宝小程序,第三方小明A
2.将这些信息分别发给他们对应的开发者,那样我们就能很好的区分出来,这些token属于谁的来源
3.其他他要完成什么操作,就还是那样操作。
4.因为这里是不需要点击授权的操作,因此可以使用密码授权或者是个人授权认证。
5.注意的是个人授权,需要把他的客户端id进行设置下Passport::personalAccessClientId(2);
那样创建的会员token才能在指定的位置,个人授权是没用刷新token的,所以就只能看到3个表个数据
客户端,token表,个人客户端关系表
几个授权方式
code授权
Route::get('/login/code', function () {
$query = http_build_query([
'client_id' => '1',
'redirect_uri' => 'http://www.lv58_2.com/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://www.lv58_2.com/oauth/authorize?' . $query);
});
这个时候同时生成了token表数据,code表数据
取得的code ,再次发起token获取
'grant_type' => 'authorization_code',
Route::get('/callback', function (\Illuminate\Http\Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://www.lv58_2.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '1', // your client id
'client_secret' => 'NL8qjys3n0OAwql0DX8PjlMACXY9JE7djjzbR6E3', // your client secret
'redirect_uri' => 'http://www.lv58_2.com/callback',
'code' => $request->input('code'),
],
]);
return dump((string)$response->getBody(), true);
});
刷新令牌
Route::get('/rt', function (\Illuminate\Http\Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://www.lv58_2.com/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'def50200e27045b28f597adc9941ab90892212c2ee1db5a69bc0bc48d16b7f50a7785980b99ac42d32984881b70e5c889f143c27d68c6d275a3888d7514a4e2374a708e8c01605dbee6c2dfc7300ead5f57f46fdbbd3f2825ae6acac00cfa03343ac69d1fedfe2ce2854d0de6fedf1d06bf6299f2df93558e1412fff2e684434689b08d66999e48edc08189b9af0f4cf88130e92a8bae25b6f74585497663a81f666a94dbb0ba45a3236a147d238ce5318fd79524362d91a9ccc415a88e0007259262b87a2c5102334367608fe449b20317c2415651033c76bba3acdd339a915e94fafbab6f317406e355af6e2f4a3191e421ba9734d0d922cb329994781bf5e8ab42b6ffedccb7a1f2fb0c1bdb68f9e82f481028511a090da0e28bb4535d9b4cdd65237a27e6aa8a7a2582457d6eb2d7a60b90be5a1f6aec5a35321077709c453402b4f7662552cd66fc72c572b47a3af7efc8286a206e05fccc5d0fe2ed10149',
'client_id' => '1',
'client_secret' => 'NL8qjys3n0OAwql0DX8PjlMACXY9JE7djjzbR6E3', // your client secret
'scope' => '',
],
]);
return json_decode((string)$response->getBody(), true);
});
同时生成token表和刷新表
密码授权令牌 'grant_type' => 'password',
Route::get('/auth/password', function (\Illuminate\Http\Request $request){
$http = new \GuzzleHttp\Client();
$response = $http->post('http://www.lv58_2.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => '1cUJGEbHfFF1TpW2VMqngpd0P2BRfhkkVEWJVoIE',
'username' => '[email protected]',
'password' => '123456',
'scope' => '',
],
]);
return json_decode((string)$response->getBody(), true);
});
客户端凭证授权令牌 'grant_type' => 'client_credentials',
//客户端凭证授权令牌
Route::get('/auth/rz', function (\Illuminate\Http\Request $request){
$guzzle = new GuzzleHttp\Client;
$response = $guzzle->post('http://www.lv58_2.com/oauth/token', [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => '2',
'client_secret' => '1cUJGEbHfFF1TpW2VMqngpd0P2BRfhkkVEWJVoIE',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
});
隐式授权令牌
Route::get('/r', function () {
$query = http_build_query([
'client_id' => '1',
'redirect_uri' => 'http://www.lv58_2.com/callback',
// 'response_type' => 'code',
'response_type' => 'token',
'scope' => '',
]);
return redirect('http://www.lv58_2.com/oauth/authorize?' . $query);
});
将直接返回
Route::get('/r', function () {
$query = http_build_query([
'client_id' => '1',
'redirect_uri' => 'http://www.lv58_2.com/callback',
// 'response_type' => 'code',
'response_type' => 'token',
'scope' => '',
]);
return redirect('http://www.lv58_2.com/oauth/authorize?' . $query);
});
需要设置这个
Passport::enableImplicitGrant();
说明
密码授权令牌
表数据必须是:
默认的密钥放在/storage/下
\vendor\laravel\passport\src\Passport.php
里面设置加密密钥位置
public static function keyPath($file)
{
$file = ltrim($file, '/\\');
return static::$keyPath
? rtrim(static::$keyPath, '/\\') . DIRECTORY_SEPARATOR . $file
: storage_path($file);
}
Passport 密钥的加载路径,这可以通过使用 Passport::loadKeysFrom 方法来实现
Passport::loadKeysFrom('/secret-keys/oauth');
令牌生命周期
//有效期
Passport::tokensExpireIn(now()->addDays(15));
//过期刷新时间
Passport::refreshTokensExpireIn(now()->addDays(30));
具体查看这个页面
Passport.php
all();
};
$defaultOptions = [
'prefix' => 'oauth',
'namespace' => '\Laravel\Passport\Http\Controllers',
];
$options = array_merge($defaultOptions, $options);
Route::group($options, function ($router) use ($callback) {
$callback(new RouteRegistrar($router));
});
}
/**
* Instruct Passport to revoke other tokens when a new one is issued.
* 指示Passport在发布新令牌时撤消其他令牌。
* @deprecated since 1.0. Listen to Passport events on token creation instead.
*
* @return static
*/
public static function revokeOtherTokens()
{
return new static;
}
/**
* Instruct Passport to keep revoked tokens pruned.
*指示Passport保留已撤销的撤销令牌。
* @deprecated since 1.0. Listen to Passport events on token creation instead.
*
* @return static
*/
public static function pruneRevokedTokens()
{
return new static;
}
/**
* Set the client ID that should be used to issue personal access tokens.
*设置应该用于颁发个人访问令牌的客户端ID。
* @param int $clientId
* @return static
*/
public static function personalAccessClientId($clientId)
{
static::$personalAccessClientId = $clientId;
return new static;
}
/**
* Set the default scope(s). Multiple scopes may be an array or specified delimited by spaces.
*
* @param array|string $scope
* @return void
*/
public static function setDefaultScope($scope)
{
static::$defaultScope = is_array($scope) ? implode(' ', $scope) : $scope;
}
/**
* Get all of the defined scope IDs.
*获取所有已定义的范围ID。
* @return array
*/
public static function scopeIds()
{
return static::scopes()->pluck('id')->values()->all();
}
/**
* Determine if the given scope has been defined.
**确定是否已定义给定范围。
* @param string $id
* @return bool
*/
public static function hasScope($id)
{
return $id === '*' || array_key_exists($id, static::$scopes);
}
/**
* Get all of the scopes defined for the application.
*
* @return \Illuminate\Support\Collection
*/
public static function scopes()
{
return collect(static::$scopes)->map(function ($description, $id) {
return new Scope($id, $description);
})->values();
}
/**
* Get all of the scopes matching the given IDs.
*获取与给定ID匹配的所有范围。
* @param array $ids
* @return array
*/
public static function scopesFor(array $ids)
{
return collect($ids)->map(function ($id) {
if (isset(static::$scopes[$id])) {
return new Scope($id, static::$scopes[$id]);
}
return;
})->filter()->values()->all();
}
/**
* Define the scopes for the application.
*定义访问程序的范围。
* @param array $scopes
* @return void
*/
public static function tokensCan(array $scopes)
{
static::$scopes = $scopes;
}
/**
* Get or set when access tokens expire.
*访问令牌到期时获取或设置。
* @param \DateTimeInterface|null $date
* @return \DateInterval|static
*/
public static function tokensExpireIn(DateTimeInterface $date = null)
{
if (is_null($date)) {
return static::$tokensExpireAt
? Carbon::now()->diff(static::$tokensExpireAt)
: new DateInterval('P1Y');
}
static::$tokensExpireAt = $date;
return new static;
}
/**
* Get or set when refresh tokens expire.
*刷新令牌过期时获取或设置。
* @param \DateTimeInterface|null $date
* @return \DateInterval|static
*/
public static function refreshTokensExpireIn(DateTimeInterface $date = null)
{
if (is_null($date)) {
return static::$refreshTokensExpireAt
? Carbon::now()->diff(static::$refreshTokensExpireAt)
: new DateInterval('P1Y');
}
static::$refreshTokensExpireAt = $date;
return new static;
}
/**
* Get or set when personal access tokens expire.
*个人访问令牌到期时获取或设置。
* @param \DateTimeInterface|null $date
* @return \DateInterval|static
*/
public static function personalAccessTokensExpireIn(DateTimeInterface $date = null)
{
if (is_null($date)) {
return static::$personalAccessTokensExpireAt
? Carbon::now()->diff(static::$personalAccessTokensExpireAt)
: new DateInterval('P1Y');
}
static::$personalAccessTokensExpireAt = $date;
return new static;
}
/**
* Get or set the name for API token cookies.
*获取或设置API令牌cookie的名称。
* @param string|null $cookie
* @return string|static
*/
public static function cookie($cookie = null)
{
if (is_null($cookie)) {
return static::$cookie;
}
static::$cookie = $cookie;
return new static;
}
/**
* Indicate that Passport should ignore incoming CSRF tokens.
*
* @param bool $ignoreCsrfToken
* @return static
*/
public static function ignoreCsrfToken($ignoreCsrfToken = true)
{
static::$ignoreCsrfToken = $ignoreCsrfToken;
return new static;
}
/**
* Set the current user for the application with the given scopes.
*使用给定范围设置应用程序的当前用户。
* @param \Illuminate\Contracts\Auth\Authenticatable|\Laravel\Passport\HasApiTokens $user
* @param array $scopes
* @param string $guard
* @return \Illuminate\Contracts\Auth\Authenticatable
*/
public static function actingAs($user, $scopes = [], $guard = 'api')
{
$token = Mockery::mock(Passport::tokenModel())->shouldIgnoreMissing(false);
foreach ($scopes as $scope) {
$token->shouldReceive('can')->with($scope)->andReturn(true);
}
$user->withAccessToken($token);
if (isset($user->wasRecentlyCreated) && $user->wasRecentlyCreated) {
$user->wasRecentlyCreated = false;
}
app('auth')->guard($guard)->setUser($user);
app('auth')->shouldUse($guard);
return $user;
}
/**
* Set the storage location of the encryption keys.
*设置加密密钥的存储位置。
* @param string $path
* @return void
*/
public static function loadKeysFrom($path)
{
static::$keyPath = $path;
}
/**
* The location of the encryption keys.
*加密密钥的位置。
* @param string $file
* @return string
*/
public static function keyPath($file)
{
$file = ltrim($file, '/\\');
return static::$keyPath
? rtrim(static::$keyPath, '/\\') . DIRECTORY_SEPARATOR . $file
: storage_path($file);
}
/**
* Set the auth code model class name.
*设置身份验证代码模型类名称。
* @param string $authCodeModel
* @return void
*/
public static function useAuthCodeModel($authCodeModel)
{
static::$authCodeModel = $authCodeModel;
}
/**
* Get the auth code model class name.
*
* @return string
*/
public static function authCodeModel()
{
return static::$authCodeModel;
}
/**
* Get a new auth code model instance.
*
* @return \Laravel\Passport\AuthCode
*/
public static function authCode()
{
return new static::$authCodeModel;
}
/**
* Set the client model class name.
*
* @param string $clientModel
* @return void
*/
public static function useClientModel($clientModel)
{
static::$clientModel = $clientModel;
}
/**
* Get the client model class name.
*
* @return string
*/
public static function clientModel()
{
return static::$clientModel;
}
/**
* Get a new client model instance.
*
* @return \Laravel\Passport\Client
*/
public static function client()
{
return new static::$clientModel;
}
/**
* Set the personal access client model class name.
*
* @param string $clientModel
* @return void
*/
public static function usePersonalAccessClientModel($clientModel)
{
static::$personalAccessClientModel = $clientModel;
}
/**
* Get the personal access client model class name.
*
* @return string
*/
public static function personalAccessClientModel()
{
return static::$personalAccessClientModel;
}
/**
* Get a new personal access client model instance.
*
* @return \Laravel\Passport\PersonalAccessClient
*/
public static function personalAccessClient()
{
return new static::$personalAccessClientModel;
}
/**
* Set the token model class name.
*
* @param string $tokenModel
* @return void
*/
public static function useTokenModel($tokenModel)
{
static::$tokenModel = $tokenModel;
}
/**
* Get the token model class name.
*
* @return string
*/
public static function tokenModel()
{
return static::$tokenModel;
}
/**
* Get a new personal access client model instance.
*
* @return \Laravel\Passport\Token
*/
public static function token()
{
return new static::$tokenModel;
}
/**
* Configure Passport to not register its migrations.
*
* @return static
*/
public static function ignoreMigrations()
{
static::$runsMigrations = false;
return new static;
}
/**
* Instruct Passport to enable cookie serialization.
*
* @return static
*/
public static function withCookieSerialization()
{
static::$unserializesCookies = true;
return new static;
}
/**
* Instruct Passport to disable cookie serialization.
*
* @return static
*/
public static function withoutCookieSerialization()
{
static::$unserializesCookies = false;
return new static;
}
}
题外话
use phpseclib\Crypt\RSA;
ras生产密钥对
$rsa->createKey($this->input ? (int) $this->option('length') : 4096);
命令行操作位置
protected $signature = 'passport:client
{--personal : Create a personal access token client}
{--password : Create a password grant client}
{--client : Create a client credentials grant client}
{--name= : The name of the client}
{--redirect_uri= : The URI to redirect to after authorization }
{--user_id= : The user ID the client should be assigned to }';
public function handle(ClientRepository $clients)
{
if ($this->option('personal')) {
$this->createPersonalClient($clients);
} elseif ($this->option('password')) {
$this->createPasswordClient($clients);
} elseif ($this->option('client')) {
$this->createClientCredentialsClient($clients);
} else {
$this->createAuthCodeClient($clients);
}
}
拿personal实例
public function createPersonalAccessClient($userId, $name, $redirect)
{
return tap($this->create($userId, $name, $redirect, true), function ($client) {
//创建好客户端之后,再来创建一个oauth_personal_access_clients这个表,添加刚才的客户端ID
$accessClient = Passport::personalAccessClient();
$accessClient->client_id = $client->id;
$accessClient->save();
});
}
public function create($userId, $name, $redirect, $personalAccess = false, $password = false)
{
//Laravel\Passport\Client对应这个表oauth_clients
$client = Passport::client()->forceFill([
'user_id' => $userId,
'name' => $name,
'secret' => Str::random(40),
'redirect' => $redirect,
'personal_access_client' => $personalAccess,
'password_client' => $password,
'revoked' => false,
]);
$client->save();
return $client;
}
密码创建,就没有多创建个oauth_personal_access_clients这个表,添加刚才的客户端ID
public function createPasswordGrantClient($userId, $name, $redirect)
{
return $this->create($userId, $name, $redirect, false, true);
}
题外话tap,类似回调函数,传递匿名函数和参数
使用给定值调用给定的Closure,然后返回值。
function tap($value, $callback = null)
{
if (is_null($callback)) {
return new HigherOrderTapProxy($value);
}
$callback($value);
return $value;
}
自定义迁移
如果你不想使用 Passport 的默认迁移,需要在 AppServiceProvider 的 register 方法中调用 Passport::ignoreMigrations 方法。你可以使用php artisan vendor:publish --tag=passport-migrations
导出默认迁移。
\vendor\laravel\passport\src\PassportServiceProvider.php
$this->loadViewsFrom(__DIR__.'/../resources/views', 'passport');
$this->deleteCookieOnLogout();
if ($this->app->runningInConsole()) {
$this->registerMigrations();
$this->publishes([
__DIR__.'/../database/migrations' => database_path('migrations'),
], 'passport-migrations');
$this->publishes([
__DIR__.'/../resources/views' => base_path('resources/views/vendor/passport'),
], 'passport-views');
$this->publishes([
__DIR__.'/../resources/js/components' => base_path('resources/js/components/passport'),
], 'passport-components');
$this->commands([
Console\InstallCommand::class,
Console\ClientCommand::class,
Console\KeysCommand::class,
]);
}
默认路由位置
\vendor\laravel\passport\src\RouteRegistrar.php
public function all()
{
//授权所需的路线
$this->forAuthorization();
//检索和发出访问令牌的路由
$this->forAccessTokens();
//刷新令牌
$this->forTransientTokens();
//管理客户端所需的路由
$this->forClients();
//管理个人访问令牌所需的路由
$this->forPersonalAccessTokens();
}
管理客户端
取得数据
$router->get('/clients', [
'uses' => 'ClientController@forUser',
'as' => 'passport.clients.index',
]);
public function forUser(Request $request)
{
$userId = $request->user()->getKey();//取得用户的id
//取得该认证后的用户生效的客户端DI,
return $this->clients->activeForUser($userId)->makeVisible('secret');
}
public function activeForUser($userId)
{
return $this->forUser($userId)->reject(function ($client) {
return $client->revoked;//如果是真的话,将会被移除
})->values();
}
public function forUser($userId)
{
return Passport::client()
->where('user_id', $userId)
->orderBy('name', 'asc')->get();
}
题外话
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->reject(function ($item) {
return $item > 2;
});
$filtered->all();
创建数据
$router->post('/clients', [
'uses' => 'ClientController@store',
'as' => 'passport.clients.store',
]);
public function store(Request $request)
{
$this->validation->make($request->all(), [
'name' => 'required|max:255',
'redirect' => ['required', $this->redirectRule],
])->validate();
return $this->clients->create(
$request->user()->getKey(), $request->name, $request->redirect
)->makeVisible('secret');
}
->makeVisible('secret'); 表示显示secret,尽管你在secret也要
更新
$router->put('/clients/{client_id}', [
'uses' => 'ClientController@update',
'as' => 'passport.clients.update',
]);
public function update(Request $request, $clientId)
{
$client = $this->clients->findForUser($clientId, $request->user()->getKey());
if (! $client) {
return new Response('', 404);
}
$this->validation->make($request->all(), [
'name' => 'required|max:255',
'redirect' => ['required', $this->redirectRule],
])->validate();
return $this->clients->update(
$client, $request->name, $request->redirect
);
}
public function update(Client $client, $name, $redirect)
{
$client->forceFill([
'name' => $name, 'redirect' => $redirect,
])->save();
return $client;
}
删除
$router->delete('/clients/{client_id}', [
'uses' => 'ClientController@destroy',
'as' => 'passport.clients.destroy',
]);
个人授权
Laravel\Passport\Token对应这个表oauth_access_tokens
管理个人访问令牌所需的路由
$router->get('/scopes', [
'uses' => 'ScopeController@all',
'as' => 'passport.scopes.index',
]);
取得所有的授权访问
public static function scopes()
{
return collect(static::$scopes)->map(function ($description, $id) {
return new Scope($id, $description);
})->values();
}
取得个人的tokens
$router->get('/personal-access-tokens', [
'uses' => 'PersonalAccessTokenController@forUser',
'as' => 'passport.personal.tokens.index',
]);
public function forUser(Request $request)
{
$tokens = $this->tokenRepository->forUser($request->user()->getKey());
return $tokens->load('client')->filter(function ($token) {
return $token->client->personal_access_client && ! $token->revoked;
})->values();
//最后返回所有的token表数据,然后关联了客户端表,判断客户端是否无效,无效的话过滤掉,然后最后返回
}
public function client()
{
return $this->belongsTo(Passport::clientModel());
}
public function forUser($userId)
{
return Passport::token()->where('user_id', $userId)->get();
}
创建新的
$router->post('/personal-access-tokens', [
'uses' => 'PersonalAccessTokenController@store',
'as' => 'passport.personal.tokens.store',
]);
public function store(Request $request)
{
$this->validation->make($request->all(), [
'name' => 'required|max:255',
'scopes' => 'array|in:'.implode(',', Passport::scopeIds()),
])->validate();
return $request->user()->createToken(
$request->name, $request->scopes ?: []
);
}
删除
$router->delete('/personal-access-tokens/{token_id}', [
'uses' => 'PersonalAccessTokenController@destroy',
'as' => 'passport.personal.tokens.destroy',
]);
public function destroy(Request $request, $tokenId)
{
$token = $this->tokenRepository->findForUser(
$tokenId, $request->user()->getKey()
);
if (is_null($token)) {
return new Response('', 404);
}
$token->revoke();
return new Response('', Response::HTTP_NO_CONTENT);
}
public function findForUser($id, $userId)
{
return Passport::token()->where('id', $id)->where('user_id', $userId)->first();
}
public function revoke()
{
return $this->forceFill(['revoked' => true])->save();
}
刷新令牌
return (new Response('Refreshed.'))->withCookie($this->cookieFactory->make(
$request->user()->getKey(), $request->session()->token()
));
检索和发出访问令牌的路由
//授权客户端访问用户的帐户
$this->router->post('/token', [
'uses' => 'AccessTokenController@issueToken',
'as' => 'passport.token',
'middleware' => 'throttle',
]);
$router->get('/tokens', [
'uses' => 'AuthorizedAccessTokenController@forUser',
'as' => 'passport.tokens.index',
]);
public function forUser(Request $request)
{
$tokens = $this->tokenRepository->forUser($request->user()->getKey());
return $tokens->load('client')->filter(function ($token) {
return ! $token->client->firstParty() && ! $token->revoked;
})->values();
}
$router->delete('/tokens/{token_id}', [
'uses' => 'AuthorizedAccessTokenController@destroy',
'as' => 'passport.tokens.destroy',
]);
public function destroy(Request $request, $tokenId)
{
$token = $this->tokenRepository->findForUser(
$tokenId, $request->user()->getKey()
);
if (is_null($token)) {
return new Response('', 404);
}
$token->revoke();
return new Response('', Response::HTTP_NO_CONTENT);
}
授权
$this->router->group(['middleware' => ['web', 'auth']], function ($router) {
$router->get('/authorize', [
'uses' => 'AuthorizationController@authorize',
'as' => 'passport.authorizations.authorize',
]);
$router->post('/authorize', [
'uses' => 'ApproveAuthorizationController@approve',
'as' => 'passport.authorizations.approve',
]);
$router->delete('/authorize', [
'uses' => 'DenyAuthorizationController@deny',
'as' => 'passport.authorizations.deny',
]);
});
public function authorize(ServerRequestInterface $psrRequest,
Request $request,
ClientRepository $clients,
TokenRepository $tokens)
{
return $this->withErrorHandling(function () use ($psrRequest, $request, $clients, $tokens) {
$authRequest = $this->server->validateAuthorizationRequest($psrRequest);
$scopes = $this->parseScopes($authRequest);
$token = $tokens->findValidToken(
$user = $request->user(),
$client = $clients->find($authRequest->getClient()->getIdentifier())
);
if ($token && $token->scopes === collect($scopes)->pluck('id')->all()) {
return $this->approveRequest($authRequest, $user);
}
$request->session()->put('authRequest', $authRequest);
return $this->response->view('passport::authorize', [
'client' => $client,
'user' => $user,
'scopes' => $scopes,
'request' => $request,
]);
});
}
$router->post('/authorize', [
'uses' => 'ApproveAuthorizationController@approve',
'as' => 'passport.authorizations.approve',
]);