版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/wh_xmy/article/details/86475859
背景:由於微信官方修改了 getUserInfo、authorize 接口,無法彈出授權窗口,所以現在無法實現一進入微信小程序就彈出授權窗口,只能通過 button 去觸發,這樣就需要我們加一個授權頁面去搞定了。
前提:微信授權登錄僅適用於使用微信用戶信息的用戶,如果自己的項目有完善的用戶信息(一套式開發項目),可不使用微信用戶信息;如果僅為微信小程序,則要授權、獲取用戶信息。
實現思路:自己寫一個微信授權登錄頁面讓用戶實現點擊的功能,也就是實現了通過 button 組件去觸發 getUserInof 接口。在用戶進入微 信小程序的時候,判斷用戶是否授權了,如果沒有授權的話就顯示“授權頁面”,讓用戶去執行授權的操作。如果已經授了,則直接跳過這個頁面,進入首頁。
授權頁面的代碼:
authorize.wxml
<!--pages/authorize/authorize.wxml-->
<view class="box" wx:if="{{canIUse}}">
<button class='bottom' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="bindGetUserInfo">
允許授權
</button>
</view>
<view class="box" wx:else>請升級微信版本</view>
authorize.wxss
/* pages/authorize/authorize.wxss */ page{ height:100%; width:100%; background: url(https://www.toread.com.cn/Public/sg/images/authorize.png) no-repeat 0 0; background-size:100% 100%; overflow: hidden; overflow-y: hidden; } .box{ height:100%; width:100%; padding-top:530rpx; box-sizing: border-box; } .bottom { box-sizing: border-box; border-radius: 8rpx; margin:0 34rpx; font-size: 36rpx; height:90rpx; font-family: PingFangHK-Regular; background:#ffffff; color:#000000; }
authorize.json
{
"navigationBarTitleText": "微信授權"
}
authorize.js
// pages/authorize/authorize.js
// import util from './utils/util.js';
var app = getApp();
Page({
/**
* 頁面的初始數據
*/
data: {
//判斷小程序的API,回調,參數,組件等是否在當前版本可用。
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
/**
* 生命周期函數--監聽頁面加載
*/
onLoad: function (options) {
wx.hideShareMenu();//禁用分享功能
var that = this;
// 查看是否授權
wx.getSetting({
success: function (res) {
if (res.authSetting['scope.userInfo']) {
wx.getUserInfo({
success: function (res) {
//從數據庫獲取用戶信息
// console.log(res);
// that.queryUsreInfo();
//用戶已經授權過
wx.switchTab({
url: '/pages/index/index'
})
}
});
}
}
})
},
// post請求
requestData:function(url, data0, successCallback, errorCallback) {
wx.request({
url: app.globalData.rootApi + url,
data: data0,
method: "POST",
success: function (res) {
successCallback(res);
},
error: function (res) {
errorCallback(res);
},
});
},
// 授權登錄
login: function (data0, successCallback, errorCallback){
this.requestData('Login/check', data0, successCallback, errorCallback);
},
//點擊授權按鈕
bindGetUserInfo: function (e) {
if (e.detail.userInfo) {
//用戶按了允許授權按鈕
var that = this;
// 登錄
wx.login({
success: res => {
// console.log(res);
const code = res.code;
// console.log(code);
// 獲取用戶信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已經授權,可以直接調用 getUserInfo 獲取頭像昵稱,不會彈框
wx.getUserInfo({
success: res => {
// 可以將 res 發送給后台解碼出
// console.log(res);
this.userInfo = res.userInfo;
var nickName = res.userInfo.nickName;
var avatarUrl = res.userInfo.avatarUrl;
// 存儲用戶名和頭像
wx.setStorageSync('nickName', nickName);
wx.setStorageSync('avatarUrl', avatarUrl);
var iv = res.iv;
var encryptedData = res.encryptedData;
var postData = {};
postData.code = code;
postData.iv = res.iv;
postData.encryptedData = res.encryptedData;
// console.log("postdata");
// console.log(postData);
app.globalData.userInfo = res.rawData;
//后台服務器授權登錄接口
this.login(postData,
(res) => {
// console.log("login----")
if (res.data.code == 1) {//獲取成功
// console.log("后台服務器授權登錄成功!");
var utoken = res.data.utoken;
// 先移除可能需要更改的storage
// wx.removeStorageSync('utoken');
//設置本地緩存
wx.setStorage({
key: 'utoken',
data: utoken,
});
//用戶已經授權過
wx.reLaunch({
url: '/pages/index/index'
});
}
else {
wx.showModal({
title: '溫馨提示',
content: res.data.msg
})
}
}
)
// 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之后才返回
// 所以此處加入 callback 以防止這種情況
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
}
})
} else {
//用戶按了拒絕按鈕
wx.showModal({
title: '警告',
content: '您點擊了拒絕授權,將無法進入小程序,請授權之后再進入!!!',
showCancel: false,
confirmText: '返回授權',
success: function (res) {
if (res.confirm) {
// console.log('用戶點擊了“返回授權”')
}
}
})
}
},
/**
* 生命周期函數--監聽頁面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函數--監聽頁面顯示
*/
onShow: function () {
},
/**
* 生命周期函數--監聽頁面隱藏
*/
onHide: function () {
},
/**
* 生命周期函數--監聽頁面卸載
*/
onUnload: function () {
},
/**
* 頁面相關事件處理函數--監聽用戶下拉動作
*/
onPullDownRefresh: function () {
},
/**
* 頁面上拉觸底事件的處理函數
*/
onReachBottom: function () {
},
/**
* 用戶點擊右上角分享
*/
onShareAppMessage: function () {
}
})
以上代碼可以解決新版小程序授權登錄問題,可能有部分方法需要使用app.js和util.js,下面附上部分代碼:
app.js
//app.js
import util from './utils/util.js';
var loginStatus = true;
App({
onLaunch: function () {
//獲取微信頂部導航欄高度
wx.getSystemInfo({
success: res => {
//導航高度
this.globalData.navHeight = res.statusBarHeight + 46;
console.log(res.statusBarHeight + 46)
}, fail(err) {
console.log(err);
}
})
// 展示本地存儲能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
//檢查登錄是否過期
wx.checkSession({
success: function (e) { //登錄態未過期
console.log("沒過期");
},
fail: function () { //登錄態過期了
console.log("過期了");
//重新調取授權登錄接口
util.checkLogin();
}
});
},
globalData: {
userInfo: null,
code:'',
rootApi: 'https://www.toread.com.cn/index.php/sg/'
}
})
util.js
var app = getApp();
// const rootApi = 'https://xxx/index.php/sg/';//測試環境
const rootApi = 'https://xxx/index.php/sg/';//線上環境
// 微信自定義格式化時間方法,傳入new Date()
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
/**
* 時間格式化為 時 分 秒(傳入時間為毫秒)
*/
function MillisecondToDate(msd) {
var time = parseFloat(msd) / 1000;
if (null != time && "" != time) {
if (time > 60 && time < 60 * 60) {
time = parseInt(time / 60.0) + "分鍾" + parseInt((parseFloat(time / 60.0) -
parseInt(time / 60.0)) * 60) + "秒";
}
else if (time >= 60 * 60 && time < 60 * 60 * 24) {
time = parseInt(time / 3600.0) + "小時" + parseInt((parseFloat(time / 3600.0) -
parseInt(time / 3600.0)) * 60) + "分鍾" +
parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60) + "秒";
}
else {
time = parseInt(time) + "秒";
}
}
return time;
}
/**
* 時間戳轉化為年 月 日 時 分 秒
* number: 傳入時間戳
* format:返回格式,支持自定義,但參數必須與formateArr里保持一致
*/
function zformatTime(number, format) {
var formateArr = ['Y', 'M', 'D', 'h', 'm', 's'];
var returnArr = [];
var date = new Date(number * 1000);
returnArr.push(date.getFullYear());
returnArr.push(formatNumber(date.getMonth() + 1));
returnArr.push(formatNumber(date.getDate()));
returnArr.push(formatNumber(date.getHours()));
returnArr.push(formatNumber(date.getMinutes()));
returnArr.push(formatNumber(date.getSeconds()));
for (var i in returnArr) {
format = format.replace(formateArr[i], returnArr[i]);
}
return format;
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
// post請求
function requestData(url, data0, successCallback, errorCallback) {
wx.request({
url: rootApi+url,
data: data0,
method: "POST",
success: function (res) {
successCallback(res);
},
error: function (res) {
errorCallback(res);
},
});
}
// get請求
function getRequestData(url, data0, successCallback, errorCallback) {
wx.request({
url: rootApi+url,
data: data0,
method: "GET",
success: function (res) {
successCallback(res);
},
error: function (res) {
errorCallback(res);
},
});
}
// 授權登錄
function login(data0, successCallback, errorCallback) {
requestData('Login/check', data0, successCallback, errorCallback);
}
// 用戶登陸過期重新登錄
function checkLogin() {
wx.login({
success: res => {
const code = res.code;
// 獲取用戶信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已經授權,可以直接調用 getUserInfo 獲取頭像昵稱,不會彈框
wx.getUserInfo({
success: res => {
console.log(res);
// 可以將 res 發送給后台解碼出
this.userInfo = res.userInfo;
var iv = res.iv;
var encryptedData = res.encryptedData;
var postData = {};
postData.code = code;
postData.iv = res.iv;
postData.encryptedData = res.encryptedData;
//后台服務器授權登錄接口
this.login(postData,
(res) => {
console.log("login----")
if (res.data.code == 1) {//獲取成功
console.log("檢測登陸過期后再次登錄成功!");
var utoken = res.data.utoken;
// 先移除可能需要更改的storage
// wx.removeStorageSync('utoken');
//設置本地緩存
wx.setStorage({
key: 'utoken',
data: utoken,
});
//用戶已經授權過
wx.reLaunch({
url: '/pages/index/index',
})
}
else {
wx.showModal({
title: '溫馨提示',
content: res.data.msg
})
}
}
)
// 由於 getUserInfo 是網絡請求,可能會在 Page.onLoad 之后才返回
// 所以此處加入 callback 以防止這種情況
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
}
})
}
// 去前后空格
function trim(str) {
return str.replace(/(^\s*)|(\s*$)/g, "");
}
// 提示錯誤信息
function isError(msg, that) {
that.setData({
showTopTips: true,
errorMsg: msg
})
}
// 清空錯誤信息
function clearError(that) {
that.setData({
showTopTips: false,
errorMsg: ""
})
}
//判斷字符串中是否含有表情符號
function isEmojiCharacter(substring) {
for (var i = 0; i < substring.length; i++) {
var hs = substring.charCodeAt(i);
if (0xd800 <= hs && hs <= 0xdbff) {
if (substring.length > 1) {
var ls = substring.charCodeAt(i + 1);
var uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
if (0x1d000 <= uc && uc <= 0x1f77f) {
return true;
}
}
} else if (substring.length > 1) {
var ls = substring.charCodeAt(i + 1);
if (ls == 0x20e3) {
return true;
}
} else {
if (0x2100 <= hs && hs <= 0x27ff) {
return true;
} else if (0x2B05 <= hs && hs <= 0x2b07) {
return true;
} else if (0x2934 <= hs && hs <= 0x2935) {
return true;
} else if (0x3297 <= hs && hs <= 0x3299) {
return true;
} else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030
|| hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b
|| hs == 0x2b50) {
return true;
}
}
}
}
module.exports = {
formatTime: formatTime,
zformatTime: zformatTime,
requestData: requestData,
trim: trim,
isError: isError,
clearError: clearError,
getRequestData: getRequestData,
checkLogin: checkLogin,
login:login,
formatDuring:formatDuring,
MillisecondToDate: MillisecondToDate,
isEmojiCharacter: isEmojiCharacter
}
