小程序开发讲究的就是一个敏捷软件开发模式,作为微信小程序授权也有多个项目的积累,所以想贴出来代码,让需要用到的朋友拿来即用(当然前提是需要修改自己的小程序appid和秘钥)。
- 前端调用wx.login()获取code值。
- 前端通过调用wx.getUserInfo获取iv、rawData、signature、encryptedData等加密数据,传递给服务端。
- 服务器通过code请求api--auth.code2Session,换回session_key和openid(判断用户的openid是否在数据库中不在就提交,再给前端发送token(md5用户id+时间戳) )。
- 前端发送消息到服务器时带上token,即请求服务端接口时,token作为参数与其他参数一并传来。
- 服务器验证token(需要用户数据表创建一个token字段(char 64))。
appid&secret=$this->secret&js_code=$code&grant_type=authorization_code";
//dump($url);
$result = $this->getJson($url);
if(isset($result['errcode'])){
return \Response::echoError($result['errmsg']);
}else{
$session_key = $result['session_key'];
$signature = $data['signature'];
$raw = trim($data['rawData']);
$encryptedData = https://www.it610.com/article/$data['encryptedData'];
$iv = $data['iv'];
if(empty($signature) || empty($raw) || empty($encryptedData) || empty($iv)){
return \Response::echoError('参数不完整!');
}
$signature2 = sha1($raw.$session_key);
if($signature != $signature2){
return \Response::echoError('签名错误!');
}
$user_info = new wxBizDataCrypt($this->appid, $session_key);
$errCode = $user_info->decryptData($encryptedData, $iv, $info);
if($errCode != 0){
return \Response::echoError($errCode);
}
$info = json_decode($info,true);
// 检查是否已存在该微信小程序的用户openid,存在表示之前已授权,直接更新token
$res = Model('User')
->where([
'openId' => $info['openId']
])
->first();
Model()->startTrans();
if(!$res){
$result_res = Model('User')
->create([
'nickname' => $info['nickName'],
'openid' => $info['openId'],
'headimgurl' => $info['avatarUrl'],
'gender' => $info['gender'],
'create_time' => date('Y-m-d H:i:s'),
'update_at' => date('Y-m-d H:i:s'),
]);
if(!$result_res){
Model()->rollback();
return \Response::echoError('授权失败!');
}else{
//保存当前用户登录信息(用户id等)到缓存
$loginLogic = new LoginLogic();
$loginLogic->save($result_res->id);
// 更新token
$token = md5($result.time());
Model('User')
->where([
'id' => $result_res->id
])
->update([
'token' => $token
]);
Model()->commit();
return \Response::echoSuccess($token, '授权成功!');
}
}else{
// 更新token
$token = md5($res['id'].time());
Model('User')
->where([
'id' => $res->id
])
->update([
'token' => $token
]);
Model()->commit();
return \Response::echoSuccess($token, '已授权成功!');
}
}
}/**
* curl的get请求
* @param $url
* @return mixed
*/
function getJson($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return json_decode($output, true);
}
}
对微信小程序用户加密数据的解密示例代码
sessionKey = $sessionKey;
$this->appid = $appid;
}/**
* 检验数据的真实性,并且获取解密后的明文.
* @param $encryptedData string 加密的用户数据
* @param $iv string 与用户数据一同返回的初始向量
* @param $data string 解密后的原文
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData( $encryptedData, $iv, &$data )
{
if (strlen($this->sessionKey) != 24) {
return ErrorCode::$IllegalAesKey;
}
$aesKey=base64_decode($this->sessionKey);
if (strlen($iv) != 24) {
return ErrorCode::$IllegalIv;
}
$aesIV=base64_decode($iv);
$aesCipher=base64_decode($encryptedData);
$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
$dataObj=json_decode( $result );
if( $dataObj== NULL )
{
return ErrorCode::$IllegalBuffer;
}
if( $dataObj->watermark->appid != $this->appid )
{
return ErrorCode::$IllegalBuffer;
}
$data = https://www.it610.com/article/$result;
return ErrorCode::$OK;
}
}
}
保存当前用户登录信息(用户id等)到缓存的LoginLogic.php
class LoginLogic{
/**
* 保存登录信息到缓存
* @param $user_id
*/
function save($user_id){
// 用户信息
$info = Model('User')
->where([
'id' => $user_id
])
->first([
'id',
'openid',
]);
if(empty($info)){
return '账户信息不存在';
}
session([
'user_id' => $info->id,
'openid' => $info->openid,
'is_login' => true
]);
return true;
}
}
接下来就是使用授权,创建一个公共的控制器,需要微信授权才能看到的信息都需要过这个公共的控制器。比如创建一个CommonController.php
// 判断是否小程序授权过
class CommonController
{
// 登录验证openid
public function __construct(){
// 接收验证登录的参数
$data = https://www.it610.com/Request::getData(['token',
]);
if(empty($data['token'])){
return \Response::echoError('请输入授权token参数!');
}
$res = Model('User')
->where([
'token' => $data['token']
])
->select('id')
->first();
if(!$res){
return \Response::echoError('请先授权!');
}else{
//保存当前用户登录信息
$loginLogic = new LoginLogic();
$loginLogic->save($result_res->id);
}
}
【PHP快速实现微信小程序授权】
推荐阅读
- 对GO切片的理解
- 小程序商城网站开发秒杀模块篇
- 盲盒购物网站系统开发建设 第三篇
- Netty核心概念之ChannelHandler&Pipeline&ChannelHandlerContext
- 简单的线程池实现多线程对大文件的读取
- SSH 端口转发与 SOCKS 代理
- Ubuntu16.04/Scala2.11.8安装教程
- 学习PHP中的高精度计时器HRTime扩展
- 使用OpenResty+Lua实现灰度测试(金丝雀)
- 使用源码编译安装PHP扩展