在小程序中登录的第一步,就是先获取登录凭证。我们可以使用wx.login()方法并得到一个登录凭证。
我们可以在小程序的App代码中发起登录凭证请求,也可以在其他任何Page页面代码中发起登录凭证请求,主要根据你小程序的实际需要。
具体过程 可以看上图,不多说直接上代码
login.js
userInfo: function (res) {
console.log(res)
//取得用户信息
var code=wx.getStorageSync('code')
var rawData = res.detail.rawData;
var signature = res.detail.signature;
var encryptedData =res.detail.encryptedData;
var iv = res.detail.iv;
wx.request({
url: 'http://localhost/yyh/1000jaindex.php',
data: {"code": code,
'rawData':rawData,
"signature": signature,
'iv': iv,
'encryptedData': encryptedData,
'operation_name':'op_session',
'submit':"1"
},
method: 'post',
header: {
"Content-Type": 'application/x-www-form-urlencoded;charset=utf-8'
},
success: function (res) {
console.log(res);
let res=res.data
if (res.status==200){
wx.setStorageSync("openid", res.openid)
}
}}
op_sesion.php
<?PHP
class op_session{
private $req_filename = ''; //申请的文件名
private $asker = ""; //申请的用户id或公司id
private $req_time =""; //获取当前时间用于写log; 申请时间
private $operation_name=""; //操作名称
private $result=array() ; //输出结果
private $lat="30.03"; //坐标
private $lng="121.1"; //
private $code=""; //小程序通过wx.login()取得的code登录凭证
private $signature=""; //小程序通过wx.getUserInfo() 取得的数字签名,//通过$signature与$signature2比较确定用户登陆态正确
private $rawData="" ; //小程序通过wx.getUserInfo() 取得的不包括敏感信息的用户信息原始数据字符串,用于计算签名
private $iv="" ; //小程序通过wx.getUserInfo() 取得加密算法的初始向量,
private $encryptedData="" ; //小程序通过wx.getUserInfo() 取得的包括敏感数据在内的完整用户信息的加密数据
private $openid="" ; //程序通过weixin api 取得的用户openid
private $session_key="" ; //程序通过weixin api 取得的用户session_key
private $islogin=false ; //登陆态是否正确
private $data="" ; //解密encryptedData后得到的完整用户数据
private $APPID = 'wx801071ad156f1';//自己配置
private $AppSecret = 'f25153087a0887e1250c53d8ae3b5';//自己配置
private $hold_word = array('lat','lng','operation_name','code','signature','rawData','iv','encryptedData');
private $keystr_arr=array('lat','lng','operation_name','code','signature','rawData','iv','encryptedData') ;//定义可以过用strrep过滤的输入
public function __construct($reqarr){
//获得数据
//echo "准备初始化";
if (!empty($reqarr)) {
foreach ($reqarr as $k => $v) {
//数据过滤---以后补全
if(in_array($k,$this->keystr_arr,true)){
$v =$this->strrep($v);//定义动态变量
//检查请息信息是否是$hold_word字段内
if(in_array($k,$this->hold_word,true)){
//定义动态变量
$this->$k= $v ;
//echo("赋值后".$k."=".$v."<br/>");
}
else{
// //echo "初始化中2".$k;
//PHP 中的中括号一般是用来通过数组的键名来获取数组相应的值
//把不是$hole_word字段内的 认为输入非法
$this->result = array(
'status' => 500, /* 返回状态,200 成功,500失败 */
'message'=> "非法访问" );
exit;
}
}
}
//echo "初始化成功";
}}
public function get_result(){
$this->login();
return json_encode($this->result,JSON_UNESCAPED_UNICODE);
die();
}
/*
*登录(调用wx.login获取)
* @param $code string
* @param $rawData string
* @param $signatrue string
* @param $encryptedData string
* @param $iv string
* @return $code 成功码
* @return $session3rd 第三方3rd_session
* @return $data 用户数据
*/
private function login()
{
//开发者使用登陆凭证 code 获取 session_key 和 openid
//通过sha1($rawData . $session_key)计算得出Signature2并与Signature比较
//并通过session_key 解密encryptedData后得到的完整用户数据
$APPID = $this->APPID;
$AppSecret =$this->AppSecret;
$code = $this->code;
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $APPID . "&secret=" . $AppSecret . "&js_code=" . $code . "&grant_type=authorization_code";
$arr = $this->vget($url); // 一个使用curl实现的get方法请求
//var_dump ($arr);
$arr = json_decode($arr, true);
$this->openid = $arr['openid']; //通过code 从api.weixin取得openid 和session_key
$session_key = $arr['session_key'];
$this->session_key = $session_key;
// 数据签名校验
$signature = $this->signature;
$rawData = $this->rawData;
$signature2 = sha1($rawData . $session_key); //计算得出Signature2
if ($signature != $signature2) {
return json_encode(['status' => 500, 'message' => '数据签名验证失败!'],JSON_UNESCAPED_UNICODE);
die();
}
else{
$this->result = array(
'status' => 200, /* 返回状态,200 成功,500失败 */
'message'=> "数据签名验证成功",
'openid'=>$this->openid,);
}
}
//一个使用curl实现的get方法请求
private function vget($url){
$info=curl_init();
curl_setopt($info,CURLOPT_RETURNTRANSFER,true);
curl_setopt($info,CURLOPT_HEADER,0);
curl_setopt($info,CURLOPT_NOBODY,0);
curl_setopt($info,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($info,CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($info,CURLOPT_URL,$url);
$output= curl_exec($info);
curl_close($info);
return $output;
}
//解密encryptedData 得到的完整用户数据注意解密前先应调用loing()方法取得$session_key
private function decipher(){
//echo "准备解密数据";
include_once("Vendor/wxBizDataCrypt.php"); //加载解密文件,在官方有下载
$encryptedData = $this->encryptedData;
$iv =$this->iv;
$session_key=$this->session_key;
$APPID=$this->$APPID;
$pc = new WXBizDataCrypt($APPID, $session_key);
$errCode = $pc->decryptData($encryptedData, $iv, $data); //其中$data包含用户的所有数据
if ($errCode == 0) {
$this->data=$data;
} else {
return $errCode;//打印失败信息
die;
}
}
openid 唯一对应用户身份的标识,网站可将此ID进行存储便于用户下次登录时辨识其身份,或将其与用户在网站上的原有账号进行绑定。公众号的openid的长度是28位。
其间跳过的坑: 获取openid时报错40029 invalid code
最后发现,appid与小程序里使用的不一致
Vendor/wxBizDataCrypt.php包可在腾迅获得
获取用户OpenID 参考 http://wiki.open.qq.com/wiki/mobile/获取用户OpenID
返回的公共码参考 http://wiki.open.qq.com/wiki/mobile/公共返回码说明#9000-9999.EF.BC.9AWAP.E7.BD.91.E7.AB.99.E6.8E.A5.E5.85.A5.EF.BC.8C.E6.A0.B9.E6.8D.AEAccess_Token.E8.8E.B7.E5.BE.97.E5.AF.B9.E5.BA.94.E7.94.A8.E6.88.B7.E8.BA.AB.E4.BB.BD.E7.9A.84openid.E6.97.B6.EF.BC.8C.E5.8F.91.E7.94.9F.E9.94.99.E8.AF.AF