1、写一个生成token的算法
/**
* 生成api接口的token
* @param map
* @param apikey
* @return
*/
public static String createToken(Map<String, String> map,String apikey){
StringBuffer sb=new StringBuffer();
for (String value : map.values()) {
sb.append(md5(value));
}
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd 00:00:00");
String time=format.format(new Date());
//token生成规则:md5(接口密钥+集合数据md5+今天的日期)
String token=md5(apikey+sb.toString()+time);
return token;
}
/**
* MD5加密
* @param plainText 要加密的字符串
* @return
*/
public static String md5(String plainText){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
//32位加密
return buf.toString();
// 16位的加密
//return buf.toString().substring(8, 24);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
token生成规则可以自己定义,但要保证客户端与服务端计算的Token保持一致。
2、进行post请求时,添加上我们生成的token
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time=sdf.format(new Date());
Map<String,String> datamap=new HashMap<String,String>();
datamap.put("type","query");
datamap.put("money",100);
datamap.put("time",time);
//添加token参数
String apikey="dfgdfsgertyrewtretww";
String token=createToken(postmap,apikey);
postmap.put("token",token);
//后面这里就是执行post请求了(此处代码省略)
1、我后端使用的是Thinkphp5.0框架,写个公共的控制器类ApiBase.php
<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
class ApiBase extends Controller
{
protected function _initialize(){
parent::_initialize();
//获取参数
$params = Request::instance()->param();
//验证是否超时
$this->check_time($params);
//验证token
$this->check_token($params);
}
/**
* api数据返回
* @param [int] $code [结果码]
* @param [string] $msg [接口要返回的提示信息]
* @param [array] $data [接口要返回的数据]
* @return [string] [最终的json数据]
*/
public function return_data($code, $msg = '', $data = []) {
$return_data['code'] = $code;
$return_data['msg'] = $msg;
$return_data['data'] = $data;
echo json_encode($return_data,JSON_UNESCAPED_UNICODE);
die;
}
/**
* 验证请求是否超时
* @param [array] $arr [包含时间戳的参数数组]
* @return [json] [检测结果]
*/
public function check_time($arr) {
if (!isset($arr['time']) || intval($arr['time']) <= 1) {
$this->return_data(0,'参数非法');
}
//超过5秒则超时
if (time() - strtotime($arr['time']) > 5) {
$this->return_data(0,'请求超时');
}
}
/**
* 验证token(防止篡改数据)
* @param [array] $arr [全部请求参数]
* @return [json] [token验证结果]
*/
public function check_token($arr) {
/*********** api传过来的token ***********/
if (!isset($arr['token']) || empty($arr['token'])) {
$this->return_data(0,'Token参数不能为空');
}
$api_token = $arr['token'];
unset($arr['token']);
/*********** 服务器端生成token ***********/
$md5_data = '';
foreach ($arr as $key => $value) {
$md5_data .= md5($value);
}
//token生成规则:md5(接口密钥+集合数据md5+今天的日期)
$service_token = md5(Config('api_key'). $md5_data .date('Y-m-d 00:00:00', time()));
/*********** 对比token,返回结果 ***********/
if ($api_token !== $service_token) {
$this->return_data(0,'Token令牌不正确');
}
}
}
2、api接口控制器实现类,直接继承这个ApiBase.php类即可自动验证token
<?php
namespace app\index\controller;
use think\Controller;
use think\Request;
use think\Cache;
/**
* Api接口通讯类
*/
class Api extends ApiBase
{
public function _initialize(){
parent::_initialize();
}
}