微信小程序的官方API
说明:
调用wx。()获得临时登录凭证代码,并将其发送回开发人员服务器。调用界面以换取唯一的用户ID和会话密钥。
然后,开发人员服务器可以基于用户ID生成自定义登录状态,该状态用于在后续业务逻辑中的前端和后端交互期间识别用户的身份。
注意:
会话密钥是用于加密和签名用户数据的密钥。为了应用程序自身的数据安全,开发人员服务器不应将会话密钥分发给,也不应将其提供给外界。临时登录凭据代码只能使用一次
这里仅符合官方推荐的规格
0.前提条件
有三个目的:
-微信小程序客户端
-第三方服务器端
-微信服务器端
1.检查登录名是否有效小程序登录授权开发,如果无效,请清除登录信息(wx。);
2.调用接口以获得登录凭证(代码)(wx。);然后,凭据将用于交换用户登录状态信息,包括用户的唯一标识()和此登录的会话密钥()等。用户数据的加密和解密通信需要依靠会话密钥来完成。
3.客户端获取代码并将代码发送到第三方服务器
微信小程序称为wx。获取登录凭据(代码),并调用该接口将代码发送给第三方客户端
4.第三方服务器与代码交换
将代码传输到第三方服务器,然后第三方服务器调用接口,并与代码交换代码
5.第三方服务器生成一个新的()
第三方服务器获取从请求中返回的总和,并将其保留在第一位,而不是保存到客户端;然后使用操作系统提供的实数随机算法生成一个新的
6.第三方服务器建立相应的关系并将其存储
将其另存为密钥,并将微信服务器返回的总和另存为值
7.第三方服务器将被发送到客户端
客户仅得到它。成人和儿童都不会打扰。小程序不需要知道和

8.正常请求
小程序的每个请求都将放置在请求标头中,第三方服务器将分析并确定合法性并执行正常的逻辑处理。
以下封装了一个小程序授权的登录组件
目录结构
1. .js
//检测登录是否有效,如果无效则清除登录信息 module.exports = { checkLogs() { let utoken = wx.getStorageSync("userInfo").utoken; if (typeof utoken == "undefined") { return false; } this.sendRequest({ url: '', // //检测登录是否有效的接口 data: { utoken }, method: 'POST', success: res => { if (res.data.code != 200) { wx.removeStorageSync('userInfo'); } }, fail: () => { wx.removeStorageSync('userInfo'); } }) }, //这里使用了iview框架,全局控制handleShow方法,授权登录的显示 login: function() { const selector = '#login' const pages = getCurrentPages(); const ctx = pages[pages.length - 1]; const componentCtx = ctx.selectComponent(selector); if (!componentCtx) { console.error('无法找到对应的组件,请按文档说明使用组件'); return null; } componentCtx.handleShow(); } }
app.js
var server = require('./utils/server'); App({ onLaunch: function() { server.checkLogs();//全局调用checkLogs(),检查登录是否失效 }, globalData: {} })
.wxml
注意:wx.authorize({scope: "scope.userInfo"}),无法弹出授权窗口,请使用
.js

// component/login/login.js const server = require('../../utils/server.js'); Component({ properties: { }, data: { formid: null, visible: false }, methods: { handleShow() { this.setData({ visible: true }) }, handleHide() { this.setData({ visible: false }) }, touchMove() { return false; }, cantchTap() { return false; }, getUserInfo(res) { if (res.detail.errMsg == 'getUserInfo:ok') { let userInfo = { ...res.detail.userInfo } wx.login({ success: e => { let code = e.code; //调用wx.login,获取登录凭证(code),并调用接口,将code发送到第三方客户端 server.sendRequest({ url: '', //小程序端将code传给第三方服务器端,第三方服务器端调用接口,用code换取session_key和openid data: { encryptedData: res.detail.encryptedData, iv: res.detail.iv, code: code }, method: 'POST', success: res => { if (res.data.code == 200) { userInfo = { ...userInfo, ...res.data.result } console.log(userInfo); console.log(res.data.result) wx.setStorageSync('userInfo', userInfo); //授权成功 this.triggerEvent('login', { status: 1 }) this.$Message({ content: '登录成功', type: "success" }) this.handleHide(); } else { this.triggerEvent('login', { status: 0 }) this.$Message({ content: '登录失败', type: 'error' }); this.handleHide(); } } }) } }) } else { this.triggerEvent('login', { status: 0 }) this.$Message({ content: '登录失败', type: 'error' }); this.handleHide(); } }, $Message(options) { //把iview框架里的方法抽取出来 const componentCtx = this.selectComponent("#message"); componentCtx.handleShow(options); } } })
.json
{ "component": true, "usingComponents": { "i-message": "/component/iview/message/index" //引用iview框架里全局提示框 } }
.wxss
.wxml
{{userInfo.nickName}} 未登录 我的订单 查看更多
.js
const server = require('../../utils/server.js'); Page({ data: { useInfo: null }, onLoad: function(options) {}, onShow: function() { }, onLogin(res) { // 授权成功的回调,根据子组件传过来的status if (res.detail.status == 1) { let userInfo = wx.getStorageSync('userInfo'); this.setData({ userInfo }) } }, navigateTo(option) { // 封装一个具有判断是否授权登录的跳转方法 if (wx.getStorageSync("userInfo")) { wx.navigateTo(option); } else { server.login(); } }, seeMore() { this.navigateTo({ url: '/pages/order/orderList/orderList' }) }, })
.wxss
page { background-color: #eee; } .head { width: 100%; height: 250rpx; background-color: #fff; box-sizing: border-box; padding: 0 20rpx; border-top: 1rpx solid #eee; display: flex; align-items: center; justify-content: flex-start; } .avatarImg { width: 150rpx; height: 150rpx; border-radius: 50%; } .nickname { display: inline-block; font-size: 40rpx; font-weight: 600; color: #212121; margin-left: 20rpx; } .order, .tool { margin-top: 20rpx; background-color: #fff; } .list { border-bottom: 2rpx solid #eee; height: 100rpx; box-sizing: border-box; padding: 0 20rpx; } .orderTitle { display: flex; align-items: center; justify-content: space-between; } .listTitle { color: #232323; font-size: 35rpx; } .readMore { line-height: 100rpx; font-size: 30rpx; color: #989898; display: flex; align-items: center; } .toRight { width: 28rpx; height: 28rpx; margin-left: 20rpx; }
.json
{ "usingComponents": { "login": "/component/login/login", "i-message": "/component/iview/message/index" } }
说明在代码中