小程序微信登录
2019-04-09 本文已影响174人
国王不在家
相信大家做小程序的, 对微信登录的机制都有一定的了解以及想法了;
大家八仙过海 各显神通,下面这篇文章,只是我对其的了解
如果大家有好的想法 !!!请一定 与 我交流!!!
I、处理登录的逻辑
关于会遇到的问题以及处理
-
首先请求是个异步事件,我们并不是所有接口都需要登录;
既然是异步事件, 那么我们肯定要在回调函数中进行处理
这样的话就要涉及到wx.request的封装;我们在下面讲 -
关于code的获取
登录需要用户点击微信自带的button才能获取到
<button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo"
type="warn" size="default" loading="{{loading}}" bindtap="primary">
一键登录
</button>
-
关于权限判断,以及如何判断
咱们不能所有接口都需要登录, 那样的话连审核都过不了;
这里同样需要对wx.requesrt进行封装;下面讲 -
登录的处理逻辑图:
小程序登录逻辑.png
II、wx.request的封装逻辑
1. wx.request的封装
-
基础层
a. 调用扩展层的处理函数
b. wx.request请求 -
扩展层
beforeRequest 发起请求之前 处理有无网络状态
handleRequestInportData 处理请求参数
showMask 处理遮罩层
stopLoading 停止各种的loading
handleResponse 处理返回结果 (在这里面处理是否跳转登录)
2. wx.request的封装逻辑图
小程序request请求封装.pngIII、关于登录 对wx.request的封装
当然是写在handleResponse里面的
跟后端约定好返回码 做对应的操作;
我们这边规定 如果返回 code == 401 || code == 403的话就表示没有登录
if (res.data.code == '401' || res.data.code == '403') {
console.error('没登录,去登录,并且设置状态')
// 清空之前的token
wx.removeStorageSync('accessToken');
// 正在登录中
if (that.globalData.isLogging) return true;
// 没在登录中 进入登录状态,并且设置isLogging
that.globalData.isLogging = true;
// 登录失效且不在白名单
if (!CONFIG['API_WHITE_LIST'].includes(thisUrl)) {
// 跳到登录
let pages = getCurrentPages();
for (let i in pages) {
if (pages[i].route == '/pages/login/login') {
// console.log(i)
wx.navigateBack({
delta: pages.length - (i + 1)
})
return true;
}
}
wx.navigateTo({ url: '/pages/login/login' });
return true;
}
return;
}
IV、相关代码
1. wx.request关于基础层的封装
// 基础层:
// 基于微信的request进行二次封装,myRequest是基础层
// beforeRequest 处理有无网络状态
// handleRequestInportData 处理请求参数
// showMask 处理遮罩层
// stopLoading 停止各种的loading
// handleResponse 处理返回结果
myRequest: function (url, data, methods, callback, loadType, errorFun, headers) {
let _this = this;
// 检查是拥有网络 没有网络 就return;
if (_this.beforeRequest(url)) return;
// 参数处理
let theData = this.handleRequestInportData(url, data, methods, callback, loadType, errorFun, headers, _this);
// 处理遮罩层
this.showMask(theData.loadType);
// 是否是启用模拟数据
if (DEBUG) {
let responseData = myData.getData(url, data);
setTimeout(() => {
console.log('DEBUG response : ')
console.log(responseData.data)
_this.stopLoading();
callback(responseData)
// _this.handleResponse(responseData, theData);
}, 800)
}else{
// 开始请求
wx.request({
url: theData.url,
data: {
...theData.data,
..._this.globalData.otherParams
},
method: theData.methods,
header: theData.headers,
success: function (res) {
// 处理返回结果
_this.handleResponse(res, theData, _this, url);
},
fail: function (err) {
_this.stopLoading();
},
complete: function () {
}
})
}
// 请求结束
},
2. wx.request 扩展层的封装
// 在请求发起之前需要做的事情 处理有无网络状态
beforeRequest: function(tempUrl) {
let _this = this;
wx.getNetworkType({
success: function (res) {
if (res.networkType == 'none') {
return true;
}
}
})
},
// 处理请求参数:
handleRequestInportData: (
url,
data,
methods = 'post',
callback = () => console.log('未传入回调callback'),
loadType = 'mask',
errorFun = (err) => {
wx.hideLoading();
wx.showToast({
title: err.message,
icon: 'none',
mask: true,
duration: 2000
})
console.log('未传入回调 errorFun')
},
headers = {},
that
) => {
let requestData = {};
if (!url) {
console.error('传入myRequest的URL不可为空');
return;
}
headers = {
'content-type': 'application/json',
'Authorization': 'Bearer ' + that.globalData.accessToken,
'enctype': 'raw'
}
data.referrer_uid = that.globalData.referrer_uid != 0 ? that.globalData.referrer_uid : 0;
requestData.url = InterFace[url];
requestData.data = data;
requestData.methods = methods;
requestData.callback = callback;
requestData.loadType = loadType;
requestData.errorFun = errorFun;
requestData.headers = headers;
return requestData;
},
// 处理返回结果:
handleResponse: (res, theData, that, tempUrl) => {
let _this = this;
that.stopLoading();
if (res.data.code == '401' || res.data.code == '403') {
console.error('没登录,去登录,并且设置状态')
// console.error(that.globalData.isLogging)
wx.removeStorageSync('accessToken');
// 正在登录中 设置 isLogging
if (that.globalData.isLogging) return true;
that.globalData.isLogging = true;
// 登录失效且不在白名单 !wx.getStorageSync('accessToken') && !API_WHITE_LIST.includes(tempUrl)
if (!CONFIG['API_WHITE_LIST'].includes(tempUrl)) {
// 跳到登录
let pages = getCurrentPages();
// Tips: 判断页面栈中是否有login
for (let i in pages) {
if (pages[i].route == '/pages/login/login') {
wx.navigateBack({
delta: pages.length - (i + 1)
})
return true;
}
}
wx.navigateTo({ url: '/pages/login/login' });
return true;
}
return;
}
if (res.data.status == 200 && res.data.code != 0) {
// 调用错误处理函数
theData.errorFun(res.data)
return;
} else if (res.data.code == '503' || res.data.code == '500') {
// 故障页面
wx.reLaunch({
url: '/pages/error/error'
})
return;
}
// 正常情况下, 回调
if (res.data.status == 200 && res.data.code == 0) {
theData.callback(res.data);
return;
}
},
// 展示遮罩层:
showMask: (loadType) =>{
if(loadType == 'none') return;
if(loadType == 'top'){
wx.showNavigationBarLoading()
return;
}
wx.showLoading({
title: '加载中',
mask: true,
})
},
/*
* 停止各种loading状态
* @function stopLoading
* @params {}
* @barth {Constantine, 2017-11-13 17:19:15}
*/
stopLoading: () => {
wx.hideLoading();
wx.hideNavigationBarLoading()
wx.stopPullDownRefresh()
},
3. 登录页面代码
<!--pages/login/login.wxml-->
<nav title="选择登录方式"></nav>
<view class='cul-null'>抱歉您还未登录呢, 请点击下方授权按钮登录</view>
<view class='cul-null'>以使用更多功能</view>
<button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo" type="warn" size="default" loading="{{loading}}" bindtap="primary"> 一键登录 </button>
<button class='login-btn' plain="{{true}}" type="default" size="default" bindtap="jumpTo" data-url='/pages/loginOld/loginOld'> 手机登录 </button>
// pages/login/login.js
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
app.globalData.isLogging = false;
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
app.globalData.isLogging = false;
},
// 发起登录
getUserInfo: function (e) {
console.log(e)
this.setData({
loading: true
})
let encryptedData = e.detail.encryptedData;
let iv = e.detail.iv;
console.log('login in')
let _this = this;
wx.login({
success: ret => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var CODE = ret.code;
app.globalData.otherParams.wxcode = ret.code;
app.myRequest('login', {
wxcode: CODE,
info: e.detail.userInfo,
allInfo: e.detail,
},
'get',
function (data) {
console.log(data)
if(data.data.has_reg == false){
_this.userRegister(encryptedData, iv, data.data.openid)
console.error('没有注册过')
}else{
console.error('注册过')
wx.showToast({
title: '已有账号,登录中',
icon: 'none',
mask: true,
duration: 1500
})
_this.saveData(data);
_this.setData({
loading: false,
userInfo: data.data.memberProfile,
hasUserInfo: true
})
if (!data.data.has_phone){
// TODO: 判断用户有没有手机号,没有调用接口绑定,并且完善密码
}
setTimeout(() => {
wx.navigateBack({
delta: 1
})
}, 800)
}
})
console.log('login', ret)
}
})
},
// 自动注册
userRegister: function (encryptedData, iv, openid) {
let _this = this;
app.myRequest('userRegister', {
encryptedData: encryptedData,
iv: iv,
openid: openid
},
'post',
function (data) {
console.log(data)
// 缓存数据
_this.saveData(data);
_this.setData({
userInfo: data.data.memberProfile,
member: data.data.member,
hasUserInfo: true,
hideBindBlock: false,
loading: false
})
app.globalData.newUser = true;
wx.showToast({
title: '注册成功',
icon: 'none',
mask: true,
duration: 1500
})
})
},
4.关于登录按钮的样式
不满意的话你可以让微信自带的buttom opacity = 0
然后自己写一个想要的样式放在自带的buttom的下面
结束语
能坚持到这里的已经是真爱了
希望各位大神 有好的方法 与我交流🔚