宝哥软件园

微信小程序踩坑指南

编辑:宝哥软件园 来源:互联网 时间:2021-12-04

最近因为公司业务一直在做微信小程序项目,借此机会总结记录一些最近被踩过的坑。

微信小程序登陆相关

微信小程序踩坑指南(图1)

前端调用wx.login()获取临时登录凭据代码,并通过wx.request()将代码发送给服务器(后端需要创建一个接口来接收代码)。后端检查登录凭证,参数为(appid、secret、js_code、Grant_type)appid小程序唯一标识secret小程序的app secret js_code。登录时获得的代码grant_type填写为authorization_code。

验证登录凭证,从微信服务器交换session_key会话密钥,即session _ key openid用户的唯一标识符。

Openid是用户的唯一标识符,但不建议直接用作后端服务器的每个用户标识符。Session_key是用于加密和签名用户数据的密钥。文件验证和获取用户特定信息需要Session_key。

通常,出于安全原因,这两种数据都不会发送到客户端。

在后端处理session_key后,前端处理后的字符串作为用户的登录标识符返回,通常是以令牌的形式。(用户自定义登录状态与openid session_key相关)前端接收令牌,存储在localStorage中,每次向服务器请求数据时都会随身携带,作为服务器识别用户的凭证。后续用户进入小程序时,首先调用wx.checkSession()检查登录状态,如果失败,重新启动登录过程。//app . jsconst blog in code=1000003//Const Success=100001//Success app({ onlaunch 3360 function(){ varloginlag=wx . getstorageync(' session id ')));变量=这个;If (loginFlag) {//检查session_key是否已过期wx.checkSession({ //session_key是否有效(未过期)success : function(){ var user info=wx . getstorageync(' wx user info ')if(user info){ that。globaldata.hasuserinfo=true}},//session _ key expired fail 3360 function(){//session _ key expired,再次登录到that . DoLogin();} });} else {//No skey,作为第一次登录this . dologgin();} },doLogin() { this.log()。然后(res={ this。$post('/auth ',{ code: res.code,},false)。然后(data={ wx . setstorageync(' session id ',data . session id);})})},/** *微信登录获取代码值,并将代码传递给服务器* @ returns */log(){返回新承诺(resolve={ wx . log in({ success(RES){ if(RES . errmsg==' log in 3360 OK '){ resolve(RES)} else { wx . show toast()

'none', duration: 1200 }) } }, fail() { wx.showToast({ title: '微信登录接口调用失败', icon: 'none', duration: 1200 }) } }) }) }, globalData: { baseurl: 'https://www.fake.shop' }})复制代码

网络请求封装


微信小程序中网络请求的api是wx.request(),但是这个请求是个异步回调的形式,每次发请求都要写好长一串,而且如果是嵌套的发请求,就会发现代码写的及其臃肿,所以将其 Promisefy是及其有必要的。 代码如下:

 $get(url, data = {}, needToken = true) {    let SUCCESS = 200    var that = this    needToken ? (data.token = wx.getStorageSync('ToKen')) : ''    return new Promise((resolve, reject) => {      wx.request({        url: that.globalData.baseurl + url,        method: "GET",        header: {          'content-type': 'application/json'        },        data: data,        success(e) {          if (e.data.code == SUCCESS) {            resolve(e.data)            return          }        },        fail(e) {          wx.showModal({            title: '提示',            content: '请求失败',            showCancel: false          })          reject(e)        }      })    })  },  $post(url, data = {}, needToken = true) {    let that = this    let SUCCESS = 200    let TimeOut = 1000    var that = this    needToken ? (data.token = wx.getStorageSync('ToKen')) : ''    return new Promise((resolve, reject) => {      wx.request({        url: that.globalData.baseurl + url,        method: "POST",        //此处可以根据接口文档设置header头        // header: {         //   'content-type': 'application/x-www-form-urlencoded'        // },        data: data,        success(e) {          if (e.statusCode == SUCCESS) {            if (e.data.code == SUCCESS) {              resolve(e.data)            }            else {              reject(e)              wx.showModal({                title: '提示',                content: e.data.msg,                showCancel: false,                success: function (res) {                  if (res.confirm) {                    if (e.data.code == TimeOut) { //根据实际业务返回的code码判断是否过期                      // 登录过期                      that.doLogin();                    }                  }                }              })            }          } else {            wx.showModal({              title: '提示',              content: e.data.error,              showCancel: false            })            reject(e)          }        },        fail(e) {          console.log(e)          wx.showModal({            title: '提示',            content: '请求失败',            showCancel: false          })          reject(e)        },        complete(e) {        }      })    })  },复制代码

微信公共号支付(微信浏览器)


虽然是写小程序踩坑指南,但是在微信内的H5页面支付和小程序内掉起支付还是有相似之处的,顺便记录一下。

应用场景

  • 已有 H5 商城网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程。
准备

UnionID:为了识别用户,每个用户针对每个公众号会产生一个安全的 OpenID,如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的 OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个 UnionID 网页授权: 一些复杂的业务场景下,需要以网页的形式提供服务,通过网页授权可以获取用户的openid(注:获取用户的 OpenID 是无需用户同意的,获取用户的基本信息则需用户同意) 微信 JS-SDK:是开发者在网页上通过 JavaScript 代码使用微信原生功能的工具包,开发者可以使用它在网页上录制和播放微信语音、监听微信分享、上传手机本地图片、拍照等许多能力。

业务流程时序图

微信小程序踩坑指南(图2)

主要流程
  • 网页内引入jssdk,主要有两种
    • 在需要调用 JS 接口的页面引入如下 JS 文件:res.wx.qq.com/open/js/jwe…JSSDK 使用步骤
    • 模块引入: 直接引入npm包weixin-js-sdk
    • npm install weixin-js-sdk ;

    • var wx = require('weixin-js-sdk');

  • 网页授权
    • 我的理解就是网页授权主要是为了使在微信浏览器里面打开的第三方网页,可以跟微信公共号以及用户的微信相关联的操作,最终获取用户在该公共号下的openid.
    • 网站应用微信登录是基于 OAuth2.0 协议标准构建的微信 OAuth2.0 授权登录系统。获取 openid 分为两步
      • 前端通过跳转网址获取 code,然后将code发送给后端
      • 后端然后根据 code 获取 openid。

code的获取

  • 在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的 “开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息” 的配置选项中,修改授权回调域名。本例中回调域名为www.foo.com
  • 业务流程 举例: 支付页面地址: payUrl => "www.foo.com/pay"
    1. 要跳转到支付页面时,如果是微信浏览器直接跳转href(办法有很多可以重定向也可以location.href)到 "open.weixin.qq.com/connect/oau…"+ appid +"&redirect_uri="+ URLEncoder.encode(payUrl) +"&response_type=code&scope=snsapi_base&state=123#wechat_redirect"
    2. 系统会自动跳转到 payUrl 并且返回一个参数 code 例如=> "www.aa.com/pay?code=aa…"
    3. 然后读取下code发送后端就ok了,这个大家应该都会吧。注:

URLEncoder.encode(payUrl)是非常有必要的 state参数: 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止 csrf 攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加 session 进行校验 后端获取openid的原因: 因为我是前端,不想搞这个(开玩笑的

更多资讯
游戏推荐
更多+