api数据安全之sign校验
1:前端:根据key,将当前13位时间戳通过aes加密生成的密文放到header请求头的sign属性中
2:后端:接收header头的sign属性的值,通过aes解密,得到13位时间戳。如果时间戳的时间是五秒之前的或者大于当前时间。
则sign错误不予放行;
php代码
common.php
<?php namespace app\api\controller; use think\Controller; use app\common\lib\IAuth; use think\Facade\Cache; // API模块 公共的控制器 class Common extends Controller { public $headers = ''; // 初始化的方法 public function __construct(){ // 校验sign值 $this->checkRequestAuth(); parent::__construct(); } // 检查每次app请求的数据是否合法 public function checkRequestAuth(){ // 实现需要获取headers的数据 $headers = request()->header(); // 基础参数校验 if(empty($headers['sign'])){ AException('sign不存在', 401); } if(!IAuth::checkSignPass($headers['sign'])){ AException('sign校验失败', 401); } // 通过,存入缓存(实现sign的使用即失效 Cache::set($headers['sign'], 1, config('IAuth.sign_cache_time')); // 存到成员属性中,供子类调用 $this->headers = $headers; } }
IAuth.php
<?php /** .------------------------------------------------------------------- * | Author: OkCoder <1046512080@qq.com> * | Git: https://www.gitee.com/okcoder * | Copyright (c) 2012-2019, www.i5920.com. All Rights Reserved. * '-------------------------------------------------------------------*/ namespace app\common\lib; use think\Facade\Cache; class IAuth { /** * 设置密码 * @param string $data 字符串 * @return string */ public static function setPassword($str) { return md5($str.config('IAuth.password_salt')); } /** * 模拟前端工程师加密。生成每次请求的sign * @param string $data 字符串 * @return string */ public static function setSign($time = '') { if(empty($time)) $time = Time::get13TimeStamp(); // 加密 $res = Aes::encode($time); return $res; } /* * 检测每次生成的sign */ public static function checkSignPass($sign){ // 解密 $str = Aes::decode($sign); // 数据规则 if(!$str || !is_numeric($str)){ return false; } // 测试时间戳,如果时间戳是五秒前的则错误 $now = Time::get13TimeStamp(); if( $now - $str > config('IAuth.sign_time') || $str > $now){ return false; } // 如果缓存中有该sign,即sign使用过,不放行 if(Cache::get($sign)){ return false; } return true; } }
Aes.php
<?php /** .------------------------------------------------------------------- * | Author: OkCoder <1046512080@qq.com> * | Git: https://www.gitee.com/okcoder * | Copyright (c) 2012-2019, www.i5920.com. All Rights Reserved. * '-------------------------------------------------------------------*/ namespace app\common\lib; class Aes { /** * 解密字符串 * @param string $data 字符串 * @return string */ public static function decode($str) { // AES模式不用vi偏移值 return openssl_decrypt(base64_decode($str),"AES-128-ECB",config('Aes.key'),OPENSSL_RAW_DATA); } /** * 加密字符串 * @param string $data 字符串 * @return string */ public static function encode($str) { //密钥 须是16位 return base64_encode(openssl_encrypt($str,"AES-128-ECB",config('Aes.key'),OPENSSL_RAW_DATA)); } }