feat: 开放API授权相关
This commit is contained in:
2
app/openapi/common.php
Normal file
2
app/openapi/common.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// 这是系统自动生成的公共文件
|
||||
37
app/openapi/controller/v1/Authorize.php
Normal file
37
app/openapi/controller/v1/Authorize.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\openapi\controller\v1;
|
||||
|
||||
use OAuth2\OAuth2;
|
||||
use OAuth2\OAuth2ServerException;
|
||||
use oauth\OAuthStorage;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class Authorize
|
||||
{
|
||||
/**
|
||||
* 获取/刷新token
|
||||
*/
|
||||
public function token()
|
||||
{
|
||||
try {
|
||||
$post = request()->post([
|
||||
'client_id',
|
||||
'client_secret',
|
||||
'grant_type',
|
||||
'refresh_token',
|
||||
]);
|
||||
$server = request()->server();
|
||||
$request = new Request([], $post, [], [], [], $server);
|
||||
$storage = new OAuthStorage;
|
||||
$oauth = new OAuth2($storage);
|
||||
$token = $oauth->grantAccessToken($request);
|
||||
return success('success', json_decode($token->getContent(), true));
|
||||
} catch (OAuth2ServerException $e) {
|
||||
return error($e->getMessage() . ' - ' . $e->getDescription());
|
||||
} catch (\Throwable $th) {
|
||||
return error($th->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
5
app/openapi/event.php
Normal file
5
app/openapi/event.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// 这是系统自动生成的event定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
5
app/openapi/middleware.php
Normal file
5
app/openapi/middleware.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
// 这是系统自动生成的middleware定义文件
|
||||
return [
|
||||
|
||||
];
|
||||
31
app/openapi/middleware/Auth.php
Normal file
31
app/openapi/middleware/Auth.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\openapi\middleware;
|
||||
|
||||
use OAuth2\OAuth2;
|
||||
use OAuth2\OAuth2ServerException;
|
||||
use oauth\OAuthStorage;
|
||||
|
||||
class Auth
|
||||
{
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param \think\Request $request
|
||||
* @param \Closure $next
|
||||
* @return Response
|
||||
*/
|
||||
public function handle($request, \Closure $next)
|
||||
{
|
||||
try {
|
||||
$oauth = new OAuth2(new OAuthStorage);
|
||||
$token = $oauth->getBearerToken();
|
||||
$oauth->verifyAccessToken($token);
|
||||
} catch (OAuth2ServerException $e) {
|
||||
return error('Unauthorized', $e->sendHttpResponse(), 401);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
32
app/openapi/model/OAuthAccessTokenModel.php
Normal file
32
app/openapi/model/OAuthAccessTokenModel.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\openapi\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* @mixin \think\Model
|
||||
*/
|
||||
class OAuthAccessTokenModel extends Model
|
||||
{
|
||||
// 表名
|
||||
protected $name = 'oauth_access_token';
|
||||
|
||||
// 字段信息
|
||||
protected $schema = [
|
||||
'id' => 'int',
|
||||
'client_id' => 'string',
|
||||
'user_id' => 'int',
|
||||
'access_token' => 'string',
|
||||
'expires' => 'int',
|
||||
'scope' => 'string',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
|
||||
// access_token范围查询
|
||||
public function scopeAccessToken($query, $access_token)
|
||||
{
|
||||
$query->where('access_token', '=', $access_token);
|
||||
}
|
||||
}
|
||||
33
app/openapi/model/OAuthAuthCodeModel.php
Normal file
33
app/openapi/model/OAuthAuthCodeModel.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\openapi\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* @mixin \think\Model
|
||||
*/
|
||||
class OAuthAuthCodeModel extends Model
|
||||
{
|
||||
// 表名
|
||||
protected $name = 'oauth_auth_code';
|
||||
|
||||
// 字段信息
|
||||
protected $schema = [
|
||||
'id' => 'int',
|
||||
'code' => 'string',
|
||||
'client_id' => 'string',
|
||||
'user_id' => 'int',
|
||||
'expires' => 'int',
|
||||
'redirect_uri' => 'string',
|
||||
'scope' => 'string',
|
||||
'created_at' => 'datetime',
|
||||
];
|
||||
|
||||
// code范围查询
|
||||
public function scopeCode($query, $code)
|
||||
{
|
||||
$query->where('code', '=', $code);
|
||||
}
|
||||
}
|
||||
33
app/openapi/model/OAuthClientModel.php
Normal file
33
app/openapi/model/OAuthClientModel.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\openapi\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* @mixin \think\Model
|
||||
*/
|
||||
class OAuthClientModel extends Model
|
||||
{
|
||||
// 表名
|
||||
protected $name = 'oauth_client';
|
||||
|
||||
// 字段信息
|
||||
protected $schema = [
|
||||
'id' => 'int',
|
||||
'client_id' => 'string',
|
||||
'client_secret' => 'string',
|
||||
'redirect_uri' => 'string',
|
||||
'enabled' => 'int',
|
||||
'created_at' => 'datetime',
|
||||
'updated_at' => 'datetime',
|
||||
'deleted_at' => 'datetime'
|
||||
];
|
||||
|
||||
// client_id范围查询
|
||||
public function scopeClientId($query, $client_id)
|
||||
{
|
||||
$query->where('client_id', '=', $client_id);
|
||||
}
|
||||
}
|
||||
32
app/openapi/model/OAuthRefreshTokenModel.php
Normal file
32
app/openapi/model/OAuthRefreshTokenModel.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\openapi\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
/**
|
||||
* @mixin \think\Model
|
||||
*/
|
||||
class OAuthRefreshTokenModel extends Model
|
||||
{
|
||||
// 表名
|
||||
protected $name = 'oauth_refresh_token';
|
||||
|
||||
// 字段信息
|
||||
protected $schema = [
|
||||
'id' => 'int',
|
||||
'client_id' => 'string',
|
||||
'user_id' => 'int',
|
||||
'refresh_token' => 'string',
|
||||
'expires' => 'int',
|
||||
'scope' => 'string',
|
||||
'created_at' => 'datetime'
|
||||
];
|
||||
|
||||
// refresh_token范围查询
|
||||
public function scopeRefreshToken($query, $refresh_token)
|
||||
{
|
||||
$query->where('refresh_token', '=', $refresh_token);
|
||||
}
|
||||
}
|
||||
35
app/openapi/route/v1.php
Normal file
35
app/openapi/route/v1.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use think\facade\Route;
|
||||
|
||||
Route::group('v1', function() {
|
||||
// 接口授权
|
||||
Route::post('authorize', 'v1.Authorize/token');
|
||||
|
||||
// 接口授权后才能访问
|
||||
Route::group(function(){
|
||||
// 获取产品列表
|
||||
Route::get('products', 'v1.Product/list');
|
||||
Route::group('product', function() {
|
||||
// 获取产品信息
|
||||
Route::get(':id', 'v1.Product/detail');
|
||||
|
||||
// 获取产品分类
|
||||
Route::get('categories', 'v1.Product/categories');
|
||||
});
|
||||
|
||||
// 获取新闻动态
|
||||
Route::get('news', 'v1.News/list');
|
||||
Route::group('news', function() {
|
||||
// 获取新闻详情
|
||||
Route::get(':id', 'v1.News/detail');
|
||||
});
|
||||
})
|
||||
->middleware(\app\openapi\middleware\Auth::class);
|
||||
})
|
||||
->middleware(\think\middleware\Throttle::class, [
|
||||
'visit_rate' => '5/m',
|
||||
'visit_fail_response' => function (\think\middleware\Throttle $throttle, \think\Request $request, int $wait_seconds) {
|
||||
return \think\Response::create('您的操作过于频繁, 请在 ' . $wait_seconds . ' 秒后再试。')->code(429);
|
||||
},
|
||||
]);
|
||||
@@ -32,7 +32,8 @@
|
||||
"topthink/think-throttle": "^2.0",
|
||||
"intervention/image": "^3.10",
|
||||
"topthink/think-cors": "^1.0",
|
||||
"phpoffice/phpspreadsheet": "^3.8"
|
||||
"phpoffice/phpspreadsheet": "^3.8",
|
||||
"friendsofsymfony/oauth2-php": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": ">=4.2",
|
||||
|
||||
42
database/migrations/20250519083010_create_oauth_client.php
Normal file
42
database/migrations/20250519083010_create_oauth_client.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class CreateOauthClient extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('oauth_client', ['engine' => 'MyISAM', 'collation' => 'utf8mb4_general_ci', 'comment' => 'OAuth 客户端表']);
|
||||
$table->addColumn('agent_id', 'integer', ['limit' => 10, 'null' => true, 'comment' => '代理ID'])
|
||||
->addColumn('client_id', 'string', ['limit' => 32, 'comment' => '客户端id'])
|
||||
->addColumn('client_secret', 'string', ['limit' => 128, 'comment' => '客户端密钥'])
|
||||
->addColumn('redirect_uri', 'string', ['limit' => 255, 'comment' => '回调地址'])
|
||||
->addColumn('enabled', 'boolean', ['default' => 1, 'comment' => '是否启用'])
|
||||
->addColumn('created_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
|
||||
->addColumn('updated_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', 'comment' => '更新时间'])
|
||||
->addColumn('deleted_at', 'timestamp', ['null' => true, 'default' => null, 'comment' => '删除时间'])
|
||||
->create();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class CreateOauthAuthCode extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('oauth_auth_code', ['engine' => 'MyISAM', 'collation' => 'utf8mb4_general_ci', 'comment' => '授权码表']);
|
||||
$table->addColumn('code', 'string', ['limit' => 64, 'null' => false, 'default' => '', 'comment' => '授权码'])
|
||||
->addColumn('client_id', 'integer', ['limit' => 11, 'null' => false, 'default' => 0, 'comment' => '客户端ID'])
|
||||
->addColumn('user_id', 'integer', ['limit' => 11, 'null' => false, 'default' => 0, 'comment' => '用户ID'])
|
||||
->addColumn('expires', 'integer', ['null' => true, 'comment' => '过期时间'])
|
||||
->addColumn('redirect_uri', 'string', ['limit' => 255, 'null' => false, 'default' => '', 'comment' => '回调地址'])
|
||||
->addColumn('scope', 'string', ['limit' => 255, 'null' => false, 'default' => '', 'comment' => '授权范围'])
|
||||
->addColumn('created_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
|
||||
->create();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class CreateOauthAccessToken extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('oauth_access_token', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => 'OAuth2访问令牌表']);
|
||||
$table->addColumn('client_id', 'string', ['limit' => 32, 'default' => '', 'comment' => '客户端ID'])
|
||||
->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '用户ID'])
|
||||
->addColumn('access_token', 'string', ['limit' => 64, 'default' => '', 'comment' => '访问令牌'])
|
||||
->addColumn('expires', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '过期时间'])
|
||||
->addColumn('scope', 'string', ['limit' => 2000, 'default' => '', 'comment' => '授权范围'])
|
||||
->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
|
||||
->create();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class CreateOauthRefreshToken extends Migrator
|
||||
{
|
||||
/**
|
||||
* Change Method.
|
||||
*
|
||||
* Write your reversible migrations using this method.
|
||||
*
|
||||
* More information on writing migrations is available here:
|
||||
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
|
||||
*
|
||||
* The following commands can be used in this method and Phinx will
|
||||
* automatically reverse them when rolling back:
|
||||
*
|
||||
* createTable
|
||||
* renameTable
|
||||
* addColumn
|
||||
* renameColumn
|
||||
* addIndex
|
||||
* addForeignKey
|
||||
*
|
||||
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||
* with the Table class.
|
||||
*/
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('oauth_refresh_token', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_general_ci', 'comment' => 'OAuth2刷新令牌表']);
|
||||
$table->addColumn('client_id', 'string', ['limit' => 32, 'default' => '', 'comment' => '客户端ID'])
|
||||
->addColumn('user_id', 'integer', ['limit' => 10, 'default' => 0, 'comment' => '用户ID'])
|
||||
->addColumn('refresh_token', 'string', ['limit' => 64, 'default' => '', 'comment' => '刷新令牌'])
|
||||
->addColumn('expires', 'integer', ['limit' => 11, 'default' => 0, 'comment' => '过期时间'])
|
||||
->addColumn('scope', 'string', ['limit' => 2000, 'default' => '', 'comment' => '授权范围'])
|
||||
->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
|
||||
->create();
|
||||
}
|
||||
}
|
||||
167
extend/oauth/OAuthStorage.php
Normal file
167
extend/oauth/OAuthStorage.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
namespace oauth;
|
||||
|
||||
use app\openapi\model\OAuthAccessTokenModel;
|
||||
use app\openapi\model\OAuthAuthCodeModel;
|
||||
use app\openapi\model\OAuthClientModel;
|
||||
use app\openapi\model\OAuthRefreshTokenModel;
|
||||
use OAuth2\IOAuth2GrantClient;
|
||||
use OAuth2\IOAuth2GrantCode;
|
||||
use OAuth2\IOAuth2RefreshTokens;
|
||||
use OAuth2\Model\IOAuth2AccessToken;
|
||||
use OAuth2\Model\IOAuth2AuthCode;
|
||||
use OAuth2\Model\IOAuth2Client;
|
||||
use OAuth2\Model\IOAuth2Token;
|
||||
use OAuth2\Model\OAuth2AccessToken;
|
||||
use OAuth2\Model\OAuth2AuthCode;
|
||||
use OAuth2\Model\OAuth2Client;
|
||||
use OAuth2\Model\OAuth2Token;
|
||||
|
||||
/**
|
||||
* OAuth2存储实现
|
||||
*/
|
||||
class OAuthStorage implements IOAuth2GrantCode, IOAuth2RefreshTokens, IOAuth2GrantClient
|
||||
{
|
||||
private $salt = '';
|
||||
|
||||
public function __construct($salt = null)
|
||||
{
|
||||
if (!is_null($salt)) {
|
||||
$this->salt = $salt;
|
||||
}
|
||||
}
|
||||
|
||||
public function addClient($client_id, $client_secret, $redirect_uri)
|
||||
{
|
||||
// 实现添加客户端的逻辑
|
||||
$client = OAuthClientModel::create([
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => hash('sha1', $client_id . $client_secret . $this->salt),
|
||||
'redirect_uri' => $redirect_uri,
|
||||
]);
|
||||
|
||||
return !$client->isEmpty();
|
||||
}
|
||||
|
||||
public function getAuthCode($code): IOAuth2AuthCode
|
||||
{
|
||||
// 实现获取授权码的逻辑
|
||||
$ret = OAuthAuthCodeModel::code($code)->find();
|
||||
if (is_null($ret)) {
|
||||
throw new \Exception('授权码不存在');
|
||||
}
|
||||
|
||||
return new OAuth2AuthCode($ret->client_id, '', $ret->expires, $ret->scope, null, $ret->redirect_uri);
|
||||
}
|
||||
|
||||
public function createAuthCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null)
|
||||
{
|
||||
// 实现创建授权码的逻辑
|
||||
$auth = OAuthAuthCodeModel::create([
|
||||
'code' => $code,
|
||||
'client_id' => $client_id,
|
||||
'user_id' => $user_id,
|
||||
'redirect_uri' => $redirect_uri,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
]);
|
||||
|
||||
return !$auth->isEmpty();
|
||||
}
|
||||
|
||||
public function markAuthCodeAsUsed($code)
|
||||
{
|
||||
// 实现标记授权码为已使用的逻辑
|
||||
OAuthAuthCodeModel::code($code)->delete();
|
||||
}
|
||||
|
||||
public function getClient($client_id): IOAuth2Client
|
||||
{
|
||||
// 实现获取客户端的逻辑
|
||||
$ret = OAuthClientModel::clientId($client_id)->find();
|
||||
if (is_null($ret)) {
|
||||
throw new \Exception('客户端不存在');
|
||||
}
|
||||
if ($ret->enabled != 1) {
|
||||
throw new \Exception('客户端已禁用');
|
||||
}
|
||||
|
||||
return new OAuth2Client($ret->client_id, $ret->client_secret, [$ret->redirect_uri]);
|
||||
}
|
||||
|
||||
public function checkClientCredentials(IOAuth2Client $client, $client_secret = null): bool
|
||||
{
|
||||
// 实现检查客户端凭证的逻辑
|
||||
$client = OAuthClientModel::clientId($client->getPublicId())->find();
|
||||
if (is_null($client)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $client->client_secret == hash('sha1', $client->client_id . $client_secret . $this->salt);
|
||||
}
|
||||
|
||||
public function getAccessToken($access_token): IOAuth2AccessToken
|
||||
{
|
||||
// 实现获取访问令牌的逻辑
|
||||
$ret = OAuthAccessTokenModel::accessToken($access_token)->find();
|
||||
if (is_null($ret)) {
|
||||
throw new \Exception('访问令牌不存在');
|
||||
}
|
||||
|
||||
return new OAuth2AccessToken($ret->client_id, $ret->access_token, $ret->expires, $ret->scope, null);
|
||||
}
|
||||
|
||||
public function createAccessToken($access_token, IOAuth2Client $client, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// 实现创建访问令牌的逻辑
|
||||
OAuthAccessTokenModel::create([
|
||||
'access_token' => $access_token,
|
||||
'client_id' => $client->getPublicId(),
|
||||
'user_id' => $user_id,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
]);
|
||||
}
|
||||
|
||||
public function checkClientCredentialsGrant(IOAuth2Client $client, $client_secret): array
|
||||
{
|
||||
// 实现检查受限授权类型的逻辑
|
||||
return ['issue_refresh_token' => true];
|
||||
}
|
||||
|
||||
public function checkRestrictedGrantType(IOAuth2Client $client, $grant_type): bool
|
||||
{
|
||||
// 实现检查受限授权类型的逻辑
|
||||
return $grant_type == 'client_credentials' || $grant_type == 'refresh_token';
|
||||
}
|
||||
|
||||
// IOAuth2RefreshTokens 接口方法实现
|
||||
public function getRefreshToken($refresh_token): IOAuth2Token
|
||||
{
|
||||
// 实现获取刷新令牌的逻辑
|
||||
$ret = OAuthRefreshTokenModel::refreshToken($refresh_token)->find();
|
||||
if (is_null($ret)) {
|
||||
throw new \Exception('刷新令牌不存在');
|
||||
}
|
||||
|
||||
return new OAuth2Token($ret->client_id, $ret->refresh_token, $ret->expires, $ret->scope, null);
|
||||
}
|
||||
|
||||
public function createRefreshToken($refresh_token, IOAuth2Client $client, $user_id, $expires, $scope = null)
|
||||
{
|
||||
// 实现创建刷新令牌的逻辑
|
||||
OAuthRefreshTokenModel::create([
|
||||
'refresh_token' => $refresh_token,
|
||||
'client_id' => $client->getPublicId(),
|
||||
'user_id' => $user_id,
|
||||
'expires' => $expires,
|
||||
'scope' => $scope,
|
||||
]);
|
||||
}
|
||||
|
||||
public function unsetRefreshToken($refresh_token)
|
||||
{
|
||||
// 实现注销刷新令牌的逻辑
|
||||
OAuthRefreshTokenModel::refreshToken($refresh_token)->delete();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user