微信小程序现在刚推出所以做了很多的限制,它差不多是封装了类似于react框架之类的进行开发,但是基本属于前端所以重要的都是后端的接口提供,但是接口的提供大家要注意因为都可以看到接口,所以需要作出严密的校验操作;【注】微信小程序采用的接口都是需要https的接口!
下面是我在Yii2封装的一个接口动作前的校验操作【当然有些动作不需要验证的后面代码中也会有表达】【可能有不足之处大家可以相互学习下---主要是加密的处理方式希望可以给大家提供到一些帮助】:
private $json_obj = [];
private $appid = '********************';
private $secret = '************************';
private $grant_type = 'authorization_code';
private $is_sign = 0;
public function beforeAction($action){//这是在所有动作执行之前进行的操作
$this->json_obj = ArrayHelper::toArray(json_decode(file_get_contents('php://input')));//微信小程序提供的参数不作处理都是数据流形式
$allow_action = ['action'];//指定不需要经过验证的动作
$mobile = empty($this->json_obj['mobile'])?"":$this->json_obj['mobile'];
$inter_face = $action->id;
if(empty($this->json_obj['code'])){
$this->is_sign = 1;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
if(!in_array($action->id,$allow_action) && !empty($this->json_obj['code'])){//需要验证的接口访问
$check_array = $this->GetWechatInfoByCode($this->json_obj['code']);//通过code来获取用户的openid和session_key 下方有此函数
if(empty($check_array['openid']) || empty($check_array['session_key'])){//如果code没刷新就去数据库查找获取openid和session_key
//在微信小程序没有重新刷新使用getInfo时code是不会变的,但是code用过是失效的所以可以去之前记录下的表中查找这条code对应的记录取出openid和session_key,将取出的openid和session_key分别赋值给$check_array['openid']和$check_array['session_key']
}else{//否则就记录最新得code和相应的openid和seesion_key
//这一步可以记录下一个code对应的有效的openid和seesion_key之类的必须参数,已做到日志的记录以及有时小程序中没有刷新信息不能及时更新code和加密串
}
if(empty($check_array['openid'])){
$this->is_sign = 2;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
$this->json_obj['openid'] = $check_array['openid'];
if(empty($check_array['session_key'])){
$this->is_sign = 3;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
$session_key = $check_array['session_key'];
if(empty($this->json_obj['rawData'])){
$this->is_sign = 4;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
if(empty($this->json_obj['signature'])){
$this->is_sign = 5;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
$rawData = $this->json_obj['rawData'];
$signature = strtolower($this->json_obj['signature']);
$sign = strtolower(sha1($rawData.$session_key));//微信小程序进行加密校验的方式
if($sign != $signature){//与传过来的密参sign进行验证
$this->is_sign = 6;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}else{
$this->is_sign = 0;return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
}
return parent::beforeAction($action); // TODO: Change the autogenerated stub
}
/**
* 利用code获取session_key以及openid
* @param $code
* @return array
*/
private function GetWechatInfoByCode($code){
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$this->appid.'&secret='.$this->secret.'&js_code='.$code.'&grant_type='.$this->grant_type;
$http = HttpHelper::initData($url,'application/x-www-form-urlencoded','','utf-8',[]);//这是封装的和curl相关的请求操作类,可以直接去curl使用的
$res = ArrayHelper::toArray(json_decode($http->doGet()));
return $res;
}
/**
* 校验有没有通过信息获取
* @return bool
*/
private function CheckSignResult(){
$ret_str = '';
switch ($this->is_sign){
case 1:
$ret_str = 'code为空';
break;
case 2:
$ret_str = 'openid为空';
break;
case 3:
$ret_str = 'session_key为空';
break;
case 4:
$ret_str = 'rawData为空';
break;
case 5:
$ret_str = 'signature为空';
break;
case 6:
$ret_str = 'sign验证失败';
break;
default:break;
}
return $ret_str;
}
当借口动作经过这样后就可以在需要校验的接口动作中加入以下代码:
if($this->is_sign != 0){
return json_encode(["Success"=>false,"Message"=>$this->CheckSignResult()]);
}
用以上过程做到进行校验,可能有不足之处,欢迎大家提出共同进步!