♻️ 重构接口权限认证方式
This commit is contained in:
@@ -2,112 +2,10 @@
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\common\model\Users;
|
||||
use app\common\traits\Core;
|
||||
use think\Controller;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\facade\Response;
|
||||
|
||||
class Base extends Controller
|
||||
{
|
||||
protected $format = 'json';
|
||||
|
||||
protected $token = null;
|
||||
|
||||
protected $user = null;
|
||||
|
||||
protected $config = null;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @throws \think\Exception\DbException
|
||||
*/
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
|
||||
$configs = \app\common\model\Config::all();
|
||||
foreach ($configs as $key => &$value) {
|
||||
$this->config[$value->name] = $value->value;
|
||||
}
|
||||
|
||||
if (!$this->config['open_api']) {
|
||||
$this->response('API is not open yet.', [], 500);
|
||||
}
|
||||
|
||||
$this->token = $this->request->header('token', $this->param('token'));
|
||||
$this->auth($this->token);
|
||||
|
||||
$format = $this->param('format');
|
||||
if ($format && in_array(strtolower($format), ['json', 'jsonp', 'xml'])) {
|
||||
$this->format = $format;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限认证,成功设置成员属性user的数据,否则直接返回失败数据
|
||||
*
|
||||
* @param $token
|
||||
*
|
||||
* @throws \think\Exception\DbException
|
||||
*/
|
||||
protected function auth($token)
|
||||
{
|
||||
if (!$token) {
|
||||
$this->response('Token does not exist.', [], 401);
|
||||
}
|
||||
$this->user = Users::get(['token' => $token]);
|
||||
if (!$this->user) {
|
||||
$this->response('Authentication failed', [], 401);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回数据给客户端并中断输出
|
||||
*
|
||||
* @param string $msg 提示信息
|
||||
* @param array $data 数据
|
||||
* @param int $code 状态码
|
||||
*
|
||||
* @throws HttpResponseException
|
||||
*/
|
||||
protected function response($msg = '', $data = [], $code = 200)
|
||||
{
|
||||
$response = Response::create([
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data ?: new \stdClass(),
|
||||
'time' => time()
|
||||
], $this->format, 200);
|
||||
|
||||
throw new HttpResponseException($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端传过来的参数
|
||||
*
|
||||
* @param string $name 参数名
|
||||
* @param null $default 默认值
|
||||
* @param string $filter 过滤方法
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
protected function param($name = '', $default = null, $filter = '')
|
||||
{
|
||||
$data = $this->request->param($name, $default, $filter);
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as &$value) {
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_string($data)) {
|
||||
return trim($data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
use Core;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ class Image extends Base
|
||||
public function initialize()
|
||||
{
|
||||
parent::initialize();
|
||||
$user = request()->user;
|
||||
$this->model = new Images();
|
||||
$this->model = $this->model->where('user_id', $this->user->id)->field(['user_id', 'folder_id'], true);
|
||||
$this->model = $this->model->where('user_id', $user->id)->field(['user_id', 'folder_id'], true);
|
||||
}
|
||||
|
||||
public function find()
|
||||
@@ -53,9 +54,9 @@ class Image extends Base
|
||||
$data = explode(',', $data);
|
||||
}
|
||||
if ($user->deleteImages($data)) {
|
||||
return $this->response('删除成功!');
|
||||
$this->response('删除成功!');
|
||||
}
|
||||
return $this->response('删除失败!', [], 500);
|
||||
$this->response('删除失败!', [], 500);
|
||||
}
|
||||
|
||||
private function parseData($data)
|
||||
@@ -64,4 +65,4 @@ class Image extends Base
|
||||
$data['upload_date'] = $data->create_time;
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,6 @@ use think\Exception;
|
||||
|
||||
class Token extends Base
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $email 邮箱
|
||||
* @param null $password 密码
|
||||
@@ -18,6 +14,7 @@ class Token extends Base
|
||||
*/
|
||||
public function index($email = null, $password = null, $refresh = false)
|
||||
{
|
||||
$user = null;
|
||||
try {
|
||||
if (!$user = Users::get(['email' => $email])) {
|
||||
throw new Exception('账号不存在');
|
||||
@@ -29,12 +26,12 @@ class Token extends Base
|
||||
$token = make_token();
|
||||
$user->token = $token;
|
||||
if (!$user->save()) {
|
||||
throw new Exception('Token刷新失败');
|
||||
throw new Exception('Token 刷新失败');
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return $this->response($e->getMessage(), null, 500);
|
||||
$this->response($e->getMessage(), null, 500);
|
||||
}
|
||||
return $this->response('success', ['token' => $user->token]);
|
||||
$this->response('success', ['token' => $user->token]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,22 +16,11 @@ class Upload extends Base
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
$config = [];
|
||||
$configs = \app\common\model\Config::all();
|
||||
foreach ($configs as $key => &$value) {
|
||||
$config[$value->name] = $value->value;
|
||||
}
|
||||
|
||||
if (!$config['open_api']) {
|
||||
$this->response('API is not open yet.', [], 500);
|
||||
}
|
||||
parent::initialize();
|
||||
|
||||
// 是否允许游客上传
|
||||
$token = $this->request->header('token', $this->param('token'));
|
||||
if (!$this->config['allowed_tourist_upload']) {
|
||||
$token && $this->auth($token);
|
||||
} else {
|
||||
$this->auth($token);
|
||||
if (!$this->getConfig('allowed_tourist_upload') && !request()->user) {
|
||||
$this->response('管理员关闭了游客上传通道');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +29,7 @@ class Upload extends Base
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data = null;
|
||||
Db::startTrans();
|
||||
try {
|
||||
|
||||
@@ -48,14 +38,14 @@ class Upload extends Base
|
||||
Db::commit();
|
||||
} catch (Exception $e) {
|
||||
Db::rollback();
|
||||
return $this->response($e->getMessage(), [], 500);
|
||||
$this->response($e->getMessage(), [], 500);
|
||||
} catch (ErrorException $e) {
|
||||
Db::rollback();
|
||||
return $this->response($e->getMessage(), [], 500);
|
||||
$this->response($e->getMessage(), [], 500);
|
||||
} catch (\Throwable $e) {
|
||||
Db::rollback();
|
||||
return $this->response($e->getMessage(), [], 500);
|
||||
$this->response($e->getMessage(), [], 500);
|
||||
}
|
||||
return $this->response('success', $data);
|
||||
$this->response('success', $data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
namespace app\common\traits;
|
||||
|
||||
use strategy\Driver;
|
||||
use think\exception\HttpResponseException;
|
||||
use think\facade\Config;
|
||||
use think\facade\Response;
|
||||
|
||||
trait Core
|
||||
{
|
||||
@@ -43,4 +45,54 @@ trait Core
|
||||
}
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回数据给客户端并中断输出
|
||||
*
|
||||
* @param string $msg 提示信息
|
||||
* @param array $data 数据
|
||||
* @param int $code 状态码
|
||||
* @param string $type 返回数据类型
|
||||
*
|
||||
* @throws HttpResponseException
|
||||
*/
|
||||
protected function response($msg = '', $data = [], $code = 200, $type = 'json')
|
||||
{
|
||||
$response = Response::create([
|
||||
'code' => $code,
|
||||
'msg' => $msg,
|
||||
'data' => $data ?: new \stdClass(),
|
||||
'time' => time()
|
||||
], $type, 200);
|
||||
|
||||
throw new HttpResponseException($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端传过来的参数
|
||||
*
|
||||
* @param string $name 参数名
|
||||
* @param null $default 默认值
|
||||
* @param string $filter 过滤方法
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
protected function param($name = '', $default = null, $filter = '')
|
||||
{
|
||||
$data = request()->param($name, $default, $filter);
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as &$value) {
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_string($data)) {
|
||||
return trim($data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,43 @@
|
||||
|
||||
namespace app\http\middleware;
|
||||
|
||||
use app\common\model\Users;
|
||||
use app\common\traits\Core;
|
||||
use think\Request;
|
||||
|
||||
class ApiAuthenticate
|
||||
{
|
||||
use Core;
|
||||
|
||||
/**
|
||||
* 允许不登录访问的路径
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $paths = [
|
||||
'api/token',
|
||||
'api/upload'
|
||||
];
|
||||
|
||||
public function handle(Request $request, \Closure $next)
|
||||
{
|
||||
$controller = $request->controller(true);
|
||||
$action = $request->action(true);
|
||||
$path = $controller . '/' . $action;
|
||||
if (!$this->getConfig('open_api')) { // 站点是否开启了接口
|
||||
$this->response('管理员关闭了接口', [], 500);
|
||||
}
|
||||
|
||||
$user = null;
|
||||
$token = $request->header('token', $this->param('token'));
|
||||
if ($token) {
|
||||
if (!$user = Users::get(['token' => $token])) {
|
||||
$this->response('认证失败', [], 401);
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($request->path(), $this->paths)) {
|
||||
if (!$token) $this->response('Token 不存在', [], 401);
|
||||
}
|
||||
|
||||
$request->user = $user;
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="mdui-textfield">
|
||||
<label class="mdui-textfield-label">注册默认</label>
|
||||
<label class="mdui-textfield-label">是否默认</label>
|
||||
<label class="mdui-switch">
|
||||
<input type="checkbox" name="default" value="1"/>
|
||||
<i class="mdui-switch-icon"></i>
|
||||
|
||||
+2
-2
@@ -14,13 +14,13 @@ use think\facade\Route;
|
||||
Route::view('compatibility', 'index@tpl/compatibility');
|
||||
|
||||
// [Api Route]
|
||||
Route::name('api')->group('api', function () {
|
||||
Route::group('api', function () {
|
||||
Route::any('token', 'api/Token/index');
|
||||
Route::any('upload', 'api/Upload/index');
|
||||
Route::any('image', 'api/Image/find');
|
||||
Route::any('images', 'api/Image/items');
|
||||
Route::any('delete', 'api/Image/delete');
|
||||
})
|
||||
})->middleware(app\http\middleware\ApiAuthenticate::class)
|
||||
->header('Access-Control-Allow-Headers', 'Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With, Token')
|
||||
->allowCrossDomain();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user