feat: 开放API授权相关

This commit is contained in:
2025-05-20 14:40:39 +08:00
parent 0b9001a739
commit 4828bde695
16 changed files with 577 additions and 1 deletions

2
app/openapi/common.php Normal file
View File

@@ -0,0 +1,2 @@
<?php
// 这是系统自动生成的公共文件

View 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
View File

@@ -0,0 +1,5 @@
<?php
// 这是系统自动生成的event定义文件
return [
];

View File

@@ -0,0 +1,5 @@
<?php
// 这是系统自动生成的middleware定义文件
return [
];

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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
View 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);
},
]);