引言:距离上次开发小程序有一年多时间了,最近又开始接触小程序的开发,对一些东西有了重新的认识,决定把实现的每个功能点记录下来,主要是开发完后,再重新写出来相信会有不一样的收获。
这个获取用户信息和手机号码都是必须得用户主动去点击,通过<button>按钮的type类型来获取不同的数据。一开始我的做法是进入小程序就让用户去授权,否则进不去。但在准备发布的时候发现官方的提示,不可以在用户不知道小程序内容情况下就强制的进行授权获取信息。所以可以换成在需要登陆的地方触发登陆,比如个人中心设置登陆和未登录状态,查看订单和购买的时候。
下面分别给出页面代码,逻辑代码和后端代码(PHP)。
一、效果



二、遇到的问题
- 常见的-41003错误:code格式解析出错
解决:在onShow方法中就使用wx.login获取到code并保存 - appSecret不能在小程序中明文出现,可以在后端使用三元判断,前端传空的就行
三、前端代码
.wxml
<view wx:if="{{isHide}}">
<view wx:if="{{canIUse}}">
<view class='header'>
<image src='../../images/member.png'></image>
</view>
<view class='content'>
<text>请依次允许获得你的公开信息及手机号码</text>
</view>
<view class="" >
<button class="{{flag?'show':'hide'}}" type="primary" open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">{{AuthorizedLogin}}</button>
<button class="{{flag?'hide':'show'}}" type="primary" lang="zh_CN" open-type='getPhoneNumber' bindgetphonenumber="getPhoneNumber">{{UserPhone}}</button>
</view>
</view>
<view wx:else>请升级微信版本</view>
</view>
.wxss
.header {
margin: 90rpx 0 90rpx 50rpx;
border-bottom: 1px solid #ccc;
text-align: center;
width: 650rpx;
height: 300rpx;
line-height: 450rpx;
}
.header image {
width: 200rpx;
height: 200rpx;
}
.content {
margin-left: 50rpx;
margin-bottom: 90rpx;
}
.content text {
display: block;
color: #9d9d9d;
margin-top: 40rpx;
}
.hide{
border-radius: 80rpx;
margin: 70rpx 50rpx;
font-size: 35rpx;
display: none;
}
.show{
display: block;
border-radius: 80rpx;
margin: 70rpx 50rpx;
font-size: 35rpx;
}
.json
{
"navigationBarTitleText": "授权页面",
"backgroundTextStyle": "dark",
"usingComponents": {}
}
.js
var util = require('../../utils/util.js');
var config = require('../../utils/config.js');
var app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
//判断小程序的API,回调,参数,组件等是否在当前版本可用。
canIUse: wx.canIUse('button.open-type.getUserInfo'),
isHide: false,
AuthorizedLogin: '授权登录',
UserPhone: '手机号授权',
lee: "",
flag: true,
code: '',
appID: '',
appSecret: '',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var that = this;
that.setData({
isHide: true
});
try {
var PHPSESSID = wx.getStorageSync('PHPSESSID')
} catch (e) {
var PHPSESSID = ''
}
if (!PHPSESSID || PHPSESSID == '') {
var session_id = app.randomStr(false, 8)
try {
wx.setStorageSync('PHPSESSID', session_id)
} catch (e) {
util.showError('save PHPSESSID cache error:' + e)
}
}
},
bindGetUserInfo: function(e) {
if (e.detail.userInfo) {
//用户按了允许授权按钮
var that = this;
console.log(e);
//授权成功后,通过改变 isHide 的值,让实现页面显示出来,把授权页面隐藏起来
that.data.lee
if (that.data.lee == '') {
wx.showToast({
icon: "none",
title: '请继续点击获取手机号',
}),
that.setData({
isHide: true,
flag: (!that.data.flag),
lee: true
})
that.wxlogin(e);
} else if (!that.data.lee) {
wx.switchTab({
url: "/pages/index/index"
})
}
} else {
//用户按了拒绝按钮
wx.showModal({
title: '警告',
content: '您点击了拒绝授权,将无法进入小程序,请授权之后再进入!!!',
showCancel: false,
confirmText: '返回授权',
success: function(res) {
// 用户没有授权成功,不需要改变 isHide 的值
if (res.confirm) {
console.log('用户点击了“返回授权”');
}
}
});
}
},
wxlogin: function (e) {
var that = this
if(typeof(e)!=="undefined"){
if (e.detail.errMsg == 'getUserInfo:fail auth deny') {
wx.showModal({
title: '提示',
content: '您已拒绝授权,请点击确定后换手机号码登录或者重新允许授权',
success: function (res) { }
})
return false
}
if(that.data.code.length == 0){
wx.login({
success: function (res) {
var code = encodeURI(res.code)
var AppID = config.AppID
var AppSecret = config.AppSecret
var encrypted = encodeURI(e.detail.encryptedData)
var iv = encodeURI(e.detail.iv)
that.setData({
code: code,
AppID: AppID,
AppSecret: AppSecret,
encrypted: encrypted,
iv:iv
})
},
fail: function(res) {
console.log('登录失败')
}
})
}
app.reqPost("Index", "login", {
code: that.data.code,
appID: that.data.AppID,
appSecret: that.data.AppSecret,
sessionid:wx.getStorageSync('PHPSESSID'),
encrypted: encodeURI(e.detail.encryptedData),
iv: encodeURI(e.detail.iv)
}, function (res) {
wx.setStorageSync('open_id', res.data.openid)
wx.setStorageSync('sessionkey', res.data.sessionkey)
})
}
},
getPhoneNumber: function(e) { //点击获取手机号码按钮
var that = this;
that.data.lee
if (that.data.lee == '') {
wx.showToast({
icon: "none",
title: '请先点击获取用户信息',
})
return
} else {
wx.checkSession({
success: function(res) {
var ency = e.detail.encryptedData;
var iv = e.detail.iv;
if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
wx.showModal({
title: '警告',
content: '您点击了拒绝授权,部分功能无法使用!!!',
showCancel: false,
confirmText: '返回授权',
success: function(res) {
// 用户没有授权成功,不需要改变 isHide 的值
if (res.confirm) {
wx.setStorageSync('enws', '1');
wx.switchTab({
url: "/wurui_house/pages/index/index"
})
console.log('用户点击了“返回授权”');
};
}
}),
that.setData({
modalstatus: true,
});
} else {
that.setData({
lee: false,
});
wx.switchTab({
url: "/pages/getphone/index"
})
//同意授权
var sessionkey = wx.getStorageSync('sessionkey');
var openid = wx.getStorageSync('open_id');
app.reqPost("Index", "getphone", {
sessionkey: sessionkey,
iv: iv,
encryptedData: ency,
openid: openid,
appID: config.AppID
}, function (res) {
util.showSuccess("获取成功")
wx.reLaunch({
url: '/pages/index/index'
})
})
}
},
fail: function() {
console.log("session_key 已经失效,需要重新执行登录流程");
that.wxlogin(); //重新登录
}
});
}
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
var that = this
wx.login({
success: function (res) {
var code = encodeURI(res.code)
var AppID = config.AppID
var AppSecret = config.AppSecret
that.setData({
code: code,
AppID: AppID,
AppSecret: AppSecret
})
console.log('进来后请求登录')
console.log(that.data.code)
},
fail: function(res) {
console.log('登录失败')
}
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
四、后端相关代码
private function _getUserInfo(){
require_once(dirname(dirname(__FILE__)).DS."resource".DS.'wxBizDataCrypt.php');
$code = $_REQUEST['code'];
$appId = $_REQUEST['appID'];
//处理appSecret
$appSecret = empty($_REQUEST['appSecret'])?"d3223726658796123b09fa899963f5":$_REQUEST['appSecret'];
$grant_type="authorization_code";
$url_get = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$appId.'&secret='.$appSecret.'&js_code='.$code.'&grant_type='.$grant_type;
$str = stripslashes($this->curlGet($url_get));
$json=json_decode($str,true);
$sessionKey = $json['session_key'];
$encryptedData=$_REQUEST['encrypted'];
$iv=$_REQUEST['iv'];
$appID=$_REQUEST['appID'];
$pc = new \WXBizDataCrypt($appID, $sessionKey);
$errCode = $pc->decryptData($encryptedData, $iv, $data );
if ($errCode == 0) {
$data = json_decode($data,true);
$data['session_key'] = $sessionKey;
return $data;
} else {
return $errCode;
}
}
一些类的代码太长了不好放,有需要的同学可以私信找我要
好了,主要逻辑都在代码中,可以在pages中新建个文件夹,将授权登陆的代码放到那里,需要登陆的时候再调用。
网友评论