让你明明白白学知识,有代码,有讲解,抄的走,学的会!
微信授权,需要经过用户主动触发,不能使用静默授权,直接调即可取获取用户数据,是不符合微信规范,在发布的时候,会被打回
外观样式
视图层
<view class="login-wrapper">
<button
class='login-btn'
type='primary'
open-type="getUserInfo"
lang="zh_CN"
bindgetuserinfo="bindGetUserInfo"
>
授权登录
</button>
<button class='cancel-btn' bindtap="cancelLogin">取消</button>
</view>
逻辑层
const {getWxCodeAPI} = require("../../apis/index")
Page({
// 取消按钮
cancelLogin() {
// getCurrentPages()获取页面栈个数
if(getCurrentPages().length === 1) {
wx.navigateTo({
url: '/pages/order/index',
})
} else {
wx.navigateBack()
}
},
// 获取头像
async bindGetUserInfo() {
let self = this;
wx.getSetting({
success: res => {
console.log("res", res)
// 用户同意了
if (res.authSetting['scope.userInfo']) {
console.log("已授权=====")
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success(res) {
console.log("获取用户信息成功", res)
// 将头像信息存储起来
wx.setStorageSync('userInfo', res.rawData)
// 直接调用登录接口--自己后台的登录系统接口
self.login()
},
fail(res) {
console.log("获取用户信息失败", res)
}
})
} else {
console.log("未授权=====")
wx.showModal({
title: '提示',
content: '授权失败,请授权后继续操作',
success(res) {
// 不需要做什么事情
}
})
}
}
})
},
login() {
// 在这个地方,就调用自己后台的登陆接口
getWxCodeAPI(() => {
// 登录以后的回调方法
wx.switchTab({
url: '/pages/form/form',
})
})
}
})
当用户点击授权,就会弹出授权窗口,点击允许,即可
-
上面其实我是在拿到用户头像以后,就直接去调用 wx.login 拿到用户的appid的code,这个code是微信生成的,获取code是没有和我们自己的服务端有任何交互请求的;
-
拿到code以后,我们才去调自己后台的登录接口,将code传过去,后台通过code能够获取到用户的信息,并存储,完成【注册/登录】
现在看一下 getWxCodeAPI这个api中做了什么事情
/apis/index.js
const {getUserAppidAPI} = require("../../utils/index")
// 自己后台的登录接口,这里比较简洁,可以自己封装 request
const loginAPI = (code)=> {
wx.request({
.....
})
}
/**
* 获取微信的code
* @param {*} callback 登录自己系统以后的回调
*/
const getWxCodeAPI = async (callback)=> {
// 将用户的appid 拿到,这个不需要授权
let code = await getUserAppidAPI()
console.log(code)
if (!code || typeof code !== 'string') {
toast('微信登录失败')
wx.removeStorageSync('code')
wx.removeStorageSync('token')
return
}
// 调用自己后台登录接口
let res = await loginAPI({
code
})
let data = res.data
if (data.code !== 0) {
wx.showModal({
title: "登录失败",
content: res.data.data.msg || ""
})
wx.removeStorageSync('code')
wx.removeStorageSync('token')
} else {
// 存储用户token
wx.setStorageSync('token', res.data.data.token)
callback && callback()
}
}
module.exports = {
getWxCodeAPI
}
/utils/index.js
/**
* 获取微信生成的code
*/
const getUserAppidAPI = ()=> {
return new Promise((resolve, reject)=> {
wx.login({
success (res) {
if (res.code) {
//发起网络请求
// 直接存起来-- 这个code 5分钟就过期了
wx.setStorageSync('code', res.code)
resolve(res.code)
} else {
wx.removeStorageSync('code')
console.log('登录失败!' + res.errMsg)
}
}
})
})
}
module.exports = {
getUserAppidAPI
}
代码分析
getWxCodeAPI中:
- 调用已经封装好的 获取wx.login中的code的接口, 使用Promise包了一层,不想使用Promise,就用回调函数
- 拿到code以后,去调自己后台的登录接口,并将后台登录的token存储到 本地,以方便其他界面读取
- getWxCodeAPI 预留了一个callback,可能我们在登录以后,需要做跳转,但是具体跳转到哪里,应用场景不同,就没做具体的控制,让回调函数去执行,当然,这里也可以使用Promise包装一层
取消按钮逻辑
-
假设用户,进入登录界面以后,并不想登录,想继续在小程序中浏览看看,此时,你不能指定跳转到哪一个界面,因为你需要跳转到用户访问过的那个界面
-
假设,用户一进入小程序,就是这个登录界面,你可能知道你需要跳转到某个具体界面A
针对上面2中情况,我们这里的取消逻辑就是
先获取页面栈 getCurrentPages() 个数,length = 1,那么就跳转到具体界面,表示是第二种情况
length > 1 则表示有后退操作,就调用 wx.navigateBack() 方法
有时候,这个登录界面只是一个中间的过渡页面,登录完成以后,还需要返回上一个界面,此时, getCurrentPages() (微信提供的全局方法) 就可以知道,当前页面栈有多少个
如果,页面栈的长度为1,也就是说,最新的页面就是当前页面,再去调用 wx.navigateBack() 将报错
重点
- 微信为了规范使用用户信息,一些敏感信息都是要用户主动同意,才能获取,不能静默获取数据
- wx.login获取的code 是不是敏感数据,可以直接静默获取,且这个code 5分钟就过期了, 所以,我们调后台接口,形成自己的登录,就是为了在code没过期之内,将用户数据存储起来
- 一定要使用button按钮,来调起授权弹窗,否则微信发布的时候,或者控制台将给你报错
<button open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button>
- 这里只是获取用户的头像权限,还有 其他的权限,思路是一样的,先用户授权,再调微信API获取
微信官方文档
番外篇
简单封装wx.request
/apis/request.js
const baseURL = 'http://www.test.cn'
module.exports.request = function (url, method = 'post', data = {}) {
return new Promise((resolve, reject) => {
wx.request({
url: baseURL + url,
data,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method,
success: res => {
resolve(res.data)
},
fail: err => {
// toast('网络故障,请稍后重试')
reject(err)
}
})
})
}
这个是最简单的,根据自己的场景,去封装工具,仅供参考