設計思路:1、前后端商定統一的加密規則;2、后端配置文件保存固定的驗證字符串;3、對前端傳的加密sign進行合法性驗證、時效驗證、唯一性驗證;
代碼如下:
1、驗證前端傳過來的sign(拋出異常的接口是我自己框架封裝的接口,沒封裝可以改成Exception)
<?php
/**
* Created by PhpStorm.
* User: hjx(2896751917@qq.com)
* Date: 2019/2/21
*/
namespace app\api\controller;
use app\common\lib\exception\ApiException;
use app\common\lib\extend\Aes;
use think\Cache;
use think\Controller;
use think\Request;
class Common extends Controller
{
protected $apiToken = null;
public function __construct(Request $request = null)
{
parent::__construct($request);
$this->verifyToken();
}
/**
* 訪問API時進行sign驗證
* @return bool
* @throws ApiException
*/
public function verifyToken() {
$data = input('param.');
$validate = validate('Common');
if(!$validate->check($data)) {
throw new ApiException($validate->getError(), 400);
}
$str = (new Aes())->decrypt($data['sign']);
if(!$str) {
throw new ApiException('sign不合法', 401);
}
list($t1,$t2) = explode('&',$str);
//sign失效時間
if(time() - $t1 > 600) {
throw new ApiException('sign已過期', 401);
}
//驗證規則
if($t2 != config('api.CorpId')) {
throw new ApiException('sign不合法', 401);
}
//驗證sign唯一性
if(Cache::get($data['sign'])) {
throw new ApiException('sign已使用過', 401);
}
Cache::set($data['sign'],1,3600);
return true;
}
}
2、各個控制器都繼承上面的Common控制器即可
3、后台加密規則
<?php
/**
* Created by PhpStorm.
* User: hjx
* Date: 2019/3/12
* Time: 10:41
*/
namespace app\api\controller;
use app\common\lib\extend\Aes;
class Test
{
/**
* token創建規則,以后前端得按照這個規則進行
* @return \app\common\lib\extend\HexString
*/
public function createToken() {
$str = time().'&'.config('api.CorpId');
return (new Aes())->encrypt($str);
}
}
后台加密只是示例的加密規則,可以給前端按照這種加密方式進行加密得到sign
