一,授权
1,首先在app.js里检测用户是否授权
// 查看是否授权
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
console.log('用户已授权' + res.authSetting['scope.userInfo']);
}
else {
console.log('用户未授权');
wx.navigateTo({
url: '../login/login'
})
}
}
})
2,没有授权就跳到授权页(单独一个页面,需要点击open-type="getUserInfo"的按钮)
<button class="cu-btn round shadow-blur lg bg-{{Theme}}" open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">授权登录</button>
3,拒绝授权或者授权失败,就让用户停留在授权页,成功则跳到首页
bindGetUserInfo: function (e) {
if (e.detail.userInfo) {
//用户按了允许授权按钮
console.log('用户按了允许授权按钮');
var that = this;
wx.navigateTo({
url: '../index/index'
})
} else {
//用户按了拒绝按钮
wx.showModal({
title: '警告',
content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入!!!',
showCancel: false,
confirmText: '返回授权',
success: function (res) {
if (res.confirm) {
console.log('用户点击了“返回授权”')
}
}
})
}
},
二,获取用户信息
1,获取openid,用户名,头像等等
在点击授权后,获取用户的信息,包括openid和unionid等等,发送给后台注册
wx: wx.getUserInfo({
withCredentials: true,//开启获取私密信息
success: function (res) {
//console.log('获取成功:' + JSON.stringify(res))
var UserInfo = JSON.stringify(res);//放入 data{},post数据的key就是UserInfo
//发送加密数据UserInfo
})
},
fail: function (res) {
console.log('获取unionid失败(组件失败)');
},
})
2,获取手机号
官方文档说明:
获取微信用户绑定的手机号,需先调用wx.login接口。 因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API
来调用,需用 button 组件的点击来触发。
注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。
使用方法 需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过
bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及
app_id 进行解密获取手机号。 代码示例 Page({ getPhoneNumber
(e) {
console.log(e.detail.errMsg)
console.log(e.detail.iv)
console.log(e.detail.encryptedData) } }) encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法
iv String 加密算法的初始向量,详细见加密数据解密算法 cloudID string 敏感数据对应的云
ID,开通云开发的小程序才会返回,可通过云调用直接获取开放数据,详细见云调用直接获取开放数据
三,注册
主要是数据库录入openid,其他可看情况获取,例如unionID,用户名,头像,手机等等
1,首先是post加密数据,放个获取到的UserInfo例子
{“errMsg”:“getUserInfo:ok”,“rawData”:"{“nickName”:“R”,“gender”:1,“language”:“zh_CN”,“city”:"",“province”:“Bronkhorstspruit”,“country”:“South
Africa”,“avatarUrl”:“https://wx.qlogo.cn/mmopen/vi_32/DQHC3FoaN1TYicamwQaCPANedQBJj9DbNRy5BXeBEglTSJJfA/132”}",“userInfo”:{“nickName”:“R”,“gender”:1,“language”:“zh_CN”,“city”:"",“province”:“Bronkhorstspruit”,“country”:“South
Africa”,“avatarUrl”:“https://wx.qlogo.cn/mmopen/vi_32/DQHC3FoaN1TYicaoQBJj9DbNRy5BXeBEglTSJJfA/132”},“signature”:“ad4a2f5834d1eb9774503f90”,“encryptedData”:“oiWQJPHfxXBszs0HcpwnEuztq8jYbMWvu9AUir/QdSGvgW7HxGgXc0zAkPPTweCmTto0la+nCl5qgw5EUPYwltIrNEDTQolPDzny4ySKT2u1YFaRtzimfg37g+9Ho0q3gsPBy44ApaLdqeBvMLVit/JwJViPxLuEUwtkNUOuyccZGkrIx4pAQpLuE0bGsuSjceMcX8kf2CM7PfM4EFRANL3Zq3UyXSRV+hHgk4kXZ6KE7pjf9IuzA3iURqQ9nYHJR2wmFCSOvjt6G0Hn2vesg9EX1/4/PAY0jryvuxoKh12fYL59lw7chybRqGrn2b1uLnrxUI7htQBVLGwrtJvs+rrd0FX1PBF1sjSQ26/X8pXA43w+k1o1fFoRElw26vipdq3OTp9iIro=”,“iv”:“sWy22akgYteA==”}
2,解密开发数据
官方说明文档解密开发数据
官方有各种后台语言的示例代码,贴一个PHP的例子
<?php
/**
* 对微信小程序用户加密数据的解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
include_once "errorCode.php";
class WXBizDataCrypt
{
private $appid;
private $sessionKey;
/**
* 构造函数
* @param $sessionKey string 用户在小程序登录后获取的会话密钥
* @param $appid string 小程序的appid
*/
public function __construct( $appid, $sessionKey)
{
$this->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 = $result;
return ErrorCode::$OK;
}
}
<?php
/**
* error code 说明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
}
?>
解密后
{
"openId": "OPENID",
"nickName": "NICKNAME",
"gender": GENDER,
"city": "CITY",
"province": "PROVINCE",
"country": "COUNTRY",
"avatarUrl": "AVATARURL",
"unionId": "UNIONID",
"watermark":
{
"appid":"APPID",
"timestamp":TIMESTAMP
}
}
{
"phoneNumber": "13580006666",
"purePhoneNumber": "13580006666",
"countryCode": "86",
"watermark":
{
"appid":"APPID",
"timestamp": TIMESTAMP
}
}
四,登录
官方说明文档:登录
function postCode() {
return new Promise(function (resolve) {
wx.login({
success: function (res) {
//console.log('code=' + res.code)
//发送请求
wx: wx.request({
url: 'login.php',
data: { code: res.code },
header: { 'content-type': 'application/x-www-form-urlencoded' },
method: 'POST',
dataType: 'json',
responseType: 'text',
success: function (res) {
console.log('登录成功返回:' + res + JSON.stringify(res))
wx.setStorageSync('sid', res.data.msg)//把返回的(自定义登录凭证=> sessionId\token) 存入本地
var newsid = res.data.msg;
resolve(newsid); //Promise成功后回调参数,相当于return。
},
fail: function (res) {
wx.showModal({
title: '温馨提示',
content: res.data.error || '网络繁忙,请稍后重试!',
showCancel: false,//关闭取消按钮
})
},
complete: function (res) { },
})
}
})
})
}
//api接口
$api = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code";
//获取GET请求
function httpGet($url){
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 500);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_URL, $url);
$res = curl_exec($curl);
curl_close($curl);
if($res=='')
httpGet($url);
$str=json_decode($res);
//print_r($str);
return $str;
}
if($code!='')
{
$wxloginSttr=httpGet($api);//发送取得用户信息
$openid = $wxloginSttr->openid;//发送取得openid
if($openid!='')
{
$onlycode='';//自定义加密,生成唯一session标识,返回给微信
$sql="";//检查用户是否存在
$sl=$db->query($sql);
$sl2=$sl->fetch();
////删除用户之前的session
unset($data);
$mdb->delete('wx_session',$data,0);
//录入登录session
unset($data);
$data["_id"]=$onlycode;
$data['session_key']=$wxloginSttr->session_key;
$data['syws_time']=time()+86400;//登陆有效期24小时
$data3=$mdb->insert('wx_session',$data);
if($data3==1)//insert==ok
{
$msg["msg"]=$onlycode;
}else
{
$msg["error"]="请重新登录!!!!";
}
}else
{
$msg["error"]="请重新登录!!!!!";
}
}else
{
$msg["error"]="非法登录!";
}
echo json_encode($msg);
五,封装request请求
官方说明文档:request组件
header 中不能设置 Referer。
content-type 默认为 application/json
data 参数说明
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String 。转换规则如下:
对于 GET 方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)
对于 POST 方法且 header[‘content-type’] 为 application/json 的数据,会对数据进行 JSON 序列化
对于 POST 方法且 header[‘content-type’] 为 application/x-www-form-urlencoded 的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)
目前自己用的封装比较简单,有基础功能,但还需不断完善改进。
/* 封装request-请求服务器
**含**传递和重获session,统一处理session异常
**不含**拦截器和单独处理其他异常
const util = require('../../utils/util.js')
util.requestUrl({
url: "接口路径",
data:{},
method:"post",
success:function(res){
console.log(res)
},
header:'请求头,可不填'
})
*/
function requestUrl({ url, data, method, success, header}) {
wx.showLoading({
title: '加载中',
})
let server = app.globalData.reURL;//正式域名
//请求头可根据实际情况填写
let header_type = header || { 'content-type': 'application/x-www-form-urlencoded', Authorization: wx.getStorageSync("sid") };
wx.request({
url: server + url,
data: data,
header: header_type,
method: method,
dataType: 'json',
responseType: 'text',
success: (res) => {
console.log(res.data);
if (登录session==OK) {
wx.hideLoading();// 隐藏加载框
success(res)
}
else if (登录session过期) {
//重新登录
postCode().then(function (locationData) {
console.log('重新获取的new-session-id:' + locationData)
//重新执行
requestUrl({
url,
data,
method,
success,
header
})
})
}
else {
wx.hideLoading();
//其他状态判为非法入侵,函数回馈提示后截断在当页
wx.showModal({
title: '温馨提示',
content: res.data.error || '网络繁忙,请稍后重试!',
showCancel: false,//关闭取消按钮
})
}
},
fail: function (res) {
wx.hideLoading();
wx.showModal({
title: '温馨提示',
content: res.data.error || '网络繁忙,请稍后重试!',
showCancel: false,
})
},
complete: function () {
}
})
}