微信服务号 扫一扫功能开发

2020-05-27  本文已影响0人  narcissus灬

扫一扫需要调用微信的js-sdk JS_SDK文档

前端部分

  1. 微信公众平台配置
    必须配置安全域名后才能使用js-sdk

    绑定域名
  2. 引入js文件
    可以通过npm i weixin-js-sdk,或者使用链接的形式

    引入js文件
  1. 通过config接口注入权限验证配置
    可以在项目开始的时候先设置wx.config配置,也可以在需要使用js-sdk的页面配置。
    配置参数来源后台的处理

    image.png
  2. 打开扫一扫


    微信扫一扫
openScan(){
  wx.ready(() => {
    wx.scanQRCode({
      needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
      scanType: ['qrCode','barCode'], // 可以指定扫二维码还是一维码,默认二者都有
      success: res =>  {
        console.log(res)
      },
      error: err => {
        console.log(err)
        if(err.errMsg.indexOf('function_not_exist') > 0){
          alert('版本过低请升级')
        }
      },
    })  
  })
}

后台部分

access token文档

  1. 微信公众平台配置ip白名单
  1. 缓存access_token
const setAccessToken = async () => {
  try {
    let url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`
    let res = await axios.get(url)
    await Redis.setAsync('access_token', res.data.access_token, 3600)
    return res.data.access_token
  } catch (error) {
    console.log(error)
    throw { errmsg: '获取access_token异常' }
  }
}
  1. 读取access_token
const getAccessToken = async () => {
  let res = null
  try {
    res = await Redis.getAsync('access_token')
    if (res == null) {
      res = await setAccessToken()
      return res
    } else {
      return res
    }
  } catch (error) {
    res = await setAccessToken()
    return res
  }
}
  1. 签名算法
    签名算法文档
    image.png
    更多介绍还是去看看文档签名算法文档
const setJsapiTicket = async () => {
  try {
    let accessToken = await getAccessToken()
    let url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`
    let res = await axios.get(url)
    await Redis.setAsync('jsapi_ticket', res.data.ticket, 3600)
    return res.data.ticket
  } catch (error) {
    console.log(error)
    throw { errmsg: '获取jsapi_ticket异常', errdata: error }
  }
}
const getJsapiTicket = async () => {
  let res = null
  try {
    res = await Redis.getAsync('jsapi_ticket')
    if (res === null) {
      res = await setJsapiTicket()
      return res
    } else {
      return res
    }
  } catch (error) {
    res = await setJsapiTicket()
    return res
  }
}
  1. 进行签名
    签名检验连接
    签名检验
const jsSHA = require('jssha')
// `obj`转`string`,需要对`key`进行排序并转为小写通过 `&` 连接
const obj2str = args => {
  let keys = Object.keys(args)
  keys = keys.sort()
  let str = ''
  keys.forEach(k => {
    str += `&${k.toLowerCase()}=args[k]`
  })
  return str.substr(1)
}

const sign = (jsapi_ticket, url) => {
  let ret = {
    jsapi_ticket: jsapi_ticket,
    nonceStr: createNonceStr(),    // 随机字符串,由开发者随机生成
    timestamp: createTimestamp(),  // 由开发者生成的当前时间戳
    url: url,
  }
  let string = raw(ret) 
  // let string = `jsapi_ticket=${ret.jsapi_ticket}&noncestr=${ret.nonceStr}&timestamp=${ret.timestamp}&url=${ret.url}`
  let shaObj = new jsSHA('SHA-1', 'TEXT')    // npm i jssha
  shaObj.update(string)
  ret.signature = shaObj.getHash('HEX')
  return ret
}
  1. 给前台返回数据
    最终返回的参数
{
  appId: "appId",
  nonceStr: "nonceStr",
  signature: "signature",
  timestamp: "timestamp",
  url: "url"
}
const { getJsapiTicket } = require('../../lib/wx')
const sign = require('./sign')
const { AppId } = require('../../env')
router.post('/wx/config', async (req, res) => {
  try {
    let url = req.body.url
    let jsapi_ticket = await getJsapiTicket()
    let wxConfig = sign(jsapi_ticket, url)
    delete wxConfig.jsapi_ticket
    delete wxConfig.url
    wxConfig.appId = AppId
    return res.json(wxConfig)
  } catch (error) {
    res.status(500).json(error)
  }
})
上一篇下一篇

猜你喜欢

热点阅读