$sign) = $tokenInfo;Log::info("check token params

时间:2021-12-21 04:33:56

这段时间和外部公司合作,一直在写对外API接口。供给的API接口是基于http协议的,也是无状态的。每次请求都必需带上身份认证信息。后台处事对身份信息进行校验。
基于HTTP协议的API身份认证有很多种方法,有HTTP Basic,HTTP Digest,API KEY,Oauth,JWK等方法,我这里只讲基于项目中的API KEY校验。

2、API KEY

API接口均通过请求头(HEADER)中通报的 TOKEN(授权令牌)来进行身份认证和鉴权, 系统会在校验 TOKEN 的正确性和时效性。
API Key就是颠末用户身份认证之后处事端给客户端分配一个API Key,类似:,,
将生成的token放在头部进行传输。

一般的措置惩罚惩罚流程如下: 一个简单的设计示例如下:

$sign) = $tokenInfo;Log::info("check token params

3、客户端生成TOKEN

计算sign和token的PHP参考代码:
设计思路:
user_id: 授权客户的 id;
app_key:开通 API 授权后获得的私钥;
ts: 倡议请求时的时间戳, 精确到秒,这个值跟接收到请求时的处事器时间戳,值偏差(正或负)赶过 1200 秒( 20 分钟)时,请求会被拒绝,要求挪用方从头生成;
token(请使用 CCT +08:00 中国北京时间);
sign: 签名字符串,对输入参数的键值key进行升序摆列,转换成型如k1=v1&k2=v2的字符串,然后拼接时间戳和app_key,最后进行sha1混淆;

function getToken($inputArr) { //当前unix时间戳 $userId = ‘3322991‘; $appKey = ‘abc123‘; $ts = time(); $sign = get_sign($inputArr, $ts, $appKey); $token = base64_encode($userId . ‘,‘ . $ts . ‘,‘ . $sign); return $token; } function getSign($inputArr, $ts, $appKey) { ksort($inputArr); $inputStr = urlencode(http_build_query($inputArr)); $sign = sha1($inputStr . $ts . $appKey); return $sign; } 4、处事端解析TOKEN

后台处事端解析TOKEN的主要思路是:
1、从新部header获取token参数;
2、按照token得到user_id、ts和sign;
3、然后按照user_id、ts和请求参数新生成签名sign;
4、校验app_key是否合法,校验ts的时效性,校验新生成的签名sign和传的签名sign是否一致。

/** * 解析TOKEN * @param $token * @param array $inputArr * @return array */ function decToken($token, $inputArr = []) { $tokenInfo = base64_decode($token); $tokenInfo = explode(‘,‘, $tokenInfo); if (count($tokenInfo) != 3) { Error::trigger(‘TOKEN信息错误‘); } list($userId, $time, $sign) = $tokenInfo; Log::info("check token params,userId:{$userId},time :{$time},sign:{$sign},inputArr:" . json_encode($inputArr)); // 时间有效性校验 if (abs(time() - $time) > \App::getConfig(‘api_token_expire_time‘)) { Error::trigger(Error::ERR_PARAM_TOKEN_TIME); } // 签名校验 $tokenObj = new Token(); // 获取用户appKey信息,按照实际项目生成app_key的法则而定 $appKey = ‘*****************‘; $generateSign = $this->getSign($inputArr, $time, $appKey); // 校验参数生成的token $newToken = $this->getToken($inputArr, $userId, $appKey, $time); Log::info("token:{$token},newToken:" . json_encode($newToken)); Log::info("sign:{$sign},newSign:" . json_encode($generateSign)); if ($sign !== $generateSign) { Error::trigger(Error::ERR_PARAM_TOKEN_SIGN); } Log::info(‘token decoded successfully‘); return $appKey; }