服務器環境: centos7 php7.0
准備工作:
- 注冊小程序,並獲取 appid 、appsecret
- 下載微信解密算法sdk : https://mp.weixin.qq.com/debug/wxadoc/dev/api/signature.html
- https 的域名。需要在小程序后台服務器域名那配置
代碼實現
一 、 thinkphp5
1 /extend/wxdev 把下載的加密算法放進去
坑1 : 微信下載的文件編碼為: UTF-8-bootom ,注意自己轉換一下(不會的直接新建文件。把代碼復制進去)
坑2 :wxBizDataCrypt.php文件中 構造函數, 微信官方使用的和類名一致, php 高版本不支持(親測: PHP5.6支持, PHP7.0 不支持)。請改為: __construct
2 新建微信配置文件: /application/extra/wechat.php
<?php // +---------------------------------------------------------------------- // | Desc: 微信配置文件 // +---------------------------------------------------------------------- // | Author: 依然范兒特西 // +---------------------------------------------------------------------- return [ //微信小程序ID "wx_appid"=>"", //微信小程序密鑰 'wx_appsecret'=>"", //微信接口域名 "wx_request_url"=>"https://api.weixin.qq.com/sns/jscode2session", ];
3 /application/common.php
/**
* 發送HTTP請求方法
* @param string $url 請求URL
* @param array $params 請求參數
* @param string $method 請求方法GET/POST
* @return array $data 響應數據
*/
function http_send($url, $params, $method = 'GET', $header = array(), $multi = false){
$opts = array(
CURLOPT_TIMEOUT => 30,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => $header
);
/* 根據請求類型設置特定參數 */
switch(strtoupper($method)){
case 'GET':
$opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
break;
case 'POST':
//判斷是否傳輸文件
$params = $multi ? $params : http_build_query($params);
$opts[CURLOPT_URL] = $url;
$opts[CURLOPT_POST] = 1;
$opts[CURLOPT_POSTFIELDS] = $params;
break;
default:
throw new Exception('不支持的請求方式!');
}
/* 初始化並執行curl請求 */
$ch = curl_init();
curl_setopt_array($ch, $opts);
$data = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if($error) throw new Exception('請求發生錯誤:' . $error);
return $data;
}
4 控制器代碼: /application/wechat/controller/Wx.php
<?php namespace app\wechat\controller; use think\Controller; //使用控制器 use think\Db; //使用數據庫操作 use think\Request; use think\config; use Wxdev\WXBizDataCrypt; /* * 微信模塊 */ class Wxrun extends Base{ function __construct(){ parent::__construct(); } public function index(){ // 指定json數據輸出 return json(['code'=>110,'message'=>"Power By 研發中心","result"=>null]); } //用戶登陸 public function user_login(){ $APPID = config::get("wechat.wx_appid"); $AppSecret = config::get("wechat.wx_appsecret"); $wx_request_url = config::get("wechat.wx_request_url"); $code = input("code"); $param = array( 'appid' => $APPID, 'secret' => $AppSecret, 'js_code' => $code, 'grant_type' => 'authorization_code' ); // 一個使用curl實現的get方法請求 $arr = http_send($wx_request_url, $param, 'post'); $arr = json_decode($arr,true); if(isset($arr['errcode']) && !empty($arr['errcode'])){ return json(['code'=>'2','message'=>$arr['errmsg'],"result"=>null]); } $openid = $arr['openid']; $session_key = $arr['session_key']; // 數據簽名校驗 $signature = input("signature"); $signature2 = sha1($_GET['rawData'].$session_key); //別用框架自帶的input,會過濾掉必要的數據 if ($signature != $signature2) { $msg = "shibai 1"; return json(['code'=>'2','message'=>'獲取失敗',"result"=>$msg]); } //開發者如需要獲取敏感數據,需要對接口返回的加密數據( encryptedData )進行對稱解密 $encryptedData = $_GET['encryptedData']; $iv = $_GET['iv']; include_once (EXTEND_PATH. 'Wxdev/wxBizDataCrypt.php'); $pc = new \WXBizDataCrypt($APPID, $session_key); $errCode = $pc->decryptData($encryptedData, $iv, $data); //其中$data包含用戶的所有數據 if ($errCode != 0) { return json(['code'=>'2','message'=>'獲取失敗',"result"=>null]); } /****** */ //寫自己的邏輯: 操作數據庫等操作 /****** */ //生成第三方3rd_session $session3rd = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol)-1; for($i=0;$i<16;$i++){ $session3rd .=$strPol[rand(0,$max)]; } return json(['code'=>'1','message'=>'獲取成功',"result"=>$session3rd]); } }
二 、 小程序代碼:
直接在 app.js 編寫
// 登錄
wx.login({
success: res => {
// 發送 res.code 到后台換取 openId, sessionKey, unionId
var code = res.code;
wx.getUserInfo({
success: res => {
// 可以將 res 發送給后台解碼出 unionId
this.globalData.userInfo = res.userInfo
var rawData = res.rawData;
var signature = res.signature;
var encryptedData = res.encryptedData;
var iv = res.iv;
wx.request({
url: 'https://www.test.com/wechat/wx/user_login',
data: {
"code": code,
"rawData": rawData,
"signature": signature,
'iv': iv,
'encryptedData': encryptedData
},
success: function (info) {
console.log(info);
}
})
// 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之后才返回
// 所以此處加入 callback 以防止這種情況
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
})
三: 測試結果:

