微信小程序+node实现登录和注册

登录

检查session(客户端) --> 登录(客户端) --> code值 --> 获取openidsession_key

客户端

客户端

// app.js
onLaunch() {
  this.checkSession()
}
// 判断微信是否存有session
checkSession() {
  wx.checkSession({
    success(res) {
      console.log('checkSession', res);
    },
    fail(error) {
      console.log('checkSession error', error);
      // 没有需要去登录获取
      // 临时登录凭证code只能使用一次
      // 调用login时 会更新session_key,使原来的失效
      wx.login({
        success(response) {
          console.log('login success', response);
          wx.request({
            url: 'https://www.wechatehttps.com/onLogin',
            data: {
              code: response.code;
            },
            success(result) {
              console.log('登录成功后返回的信息', result)
            },
            fail(err) {
              console.log('失败返回的信息', err);
            }
          })
        },
        fail(err) {
          console.log('login error', err);
        }
      })
    }
  })
}

服务端

服务端 基于express搭建的 使用request发送请求

const appid = 'wx**********';
const secret = '**************';
const authorizationCode = 'test';
let sessionKey = null;
let openid = null;

app.get('/onLogin', (req, res) => {
  // 获取到登录后的code
  const { code } = req.query;
  // 向微信服务器发送信息获取到 openid 和 session_key
  request(`https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=${authorizationCode}`, (err, response, body) => {
    if(err) console.log(err);
    const data = JSON.parse(body);
    /*
    签名校验以及数据加解密涉及用户的会话密钥session_key。 需要保存在服务器
    openid 判断是否是同一个用户
    session_key 判断用户是否失效

    data: {
      openid: '**********',
      session_key: '********'
    }
    */
   res.end(JSON.strinfy(data))
  })
})

转发和群分享

转发

  1. 开启页面转发功能

因为微信开放问题,推荐是需要转发的页面开启转发,所以默认是没有开启

// page.js
onLoad() {
  wx.showShareMenu({
    // 是否携带转发来源信息,默认false
    // 目前只有转发到群聊才有,单聊没有
    withShareTicket: true
  })
}
  1. 触发转发(页面/按钮)
//page.js
page({
  onShareAppMessage(type) {
    // from  button:页面内转发按钮;menu:右上角转发菜单
    if (res.from === 'button') {
      // 来自页面内转发按钮
      console.log(res.target)
      return {
        title: '通过按钮转发',
        // 可以通过query带参数
        path: '/page/user?id=123',
      }
    }
    return {
      title: '自定义转发标题',
      path: '/page/user?id=123'
    }
  }
})
  1. 通过转发个人进入获取转发人标识

query 里面带的参数可以在转发的 app.js onLaunch获得

// �app.js
onLaunch(info) {
  const query = info.query

}

通过转发群聊进入获取群信息

  1. 客户端请求和处理
// app.js

/*
因为回调太恶心了,所以这里用了wepy框架,
采用es6 await/async 进行异步请求
*/

onLaunch(info) {
  const self = this
  // 判断是否有转发来源
  if (info.shareTicket) {
    self.getShareInfoFun(info)
  }
}

async getShareInfoFun(info) {
  // 通过转发 shareTicket 获取 加密的用户信息
  const data = await this.getShareInfo(info)
  // 检查微信服务器的session是否失效
  const response = await this.checkSession()
  const { encryptedData, iv } = data
  /*
  通过 login 拿到code
  通过 getShareInfo 拿到 encryptedData 和 iv 的加密信息
  向服务端请求,拿到解密数据
  */
  if(response){
    wepy.request({
      url: 'https://www.wechathttps.com/onLogin',
      data: {
        code: response.code,
        encryptedData,
        iv
      },
      success(result) {
        // 返回解密后的数据
        // 拿到 openGId (群id)
        console.log('数据返回', result)
      },
      fail(err) {
        console.log('request error', err)
      }
    })
  } else {
    wepy.request({
      url: 'https://www.wechathttps.com/getOpenGid',
      data: {
        encryptedData,
        iv
      },
      success(result) {
        // 返回解密后的数据
        // 拿到 openGId (群id)
        console.log('数据返回', result)
      },
      fail(err) {
        console.log('request error', err)
      }
    })
  }

}

// 通过转发 shareTicket 获取 加密的用户信息
getShareInfo(info) {
  return new Promise((resolve, reject) => {
    wepy.getShareInfo({
      shareTicket: info.shareTicket,
      success(res) {
        console.log('getShareInfo', res)
        // 返回的是加密数据
        resolve(res)
      }
    })
  })
}
// 检查
checkSession() {
  return new Promise((resolve, reject) => {
    // 判断微信服务器上的session是否失效
    wepy.checkSession({
      // 未失效, 如果调用login会使当前session失效,再重新生成一个新的
      success(res) {
        console.log('checkSession', res)
        resolve(null)
      },
      // 失效需要重新调用login
      fail(error) {
        console.log('checkSession error', error)
        wepy.login({
          success(response) {
            // 登录成功后拿到code值用于服务器解码
            console.log('success login', response)
            resolve(response)
          },
          fail(err) {
            console.log('error login', err)
            reject(err)
          }
        })
      }
    })
  })
}
  1. 服务端获取数据和解密
//node + express + request

const express = require('express')
const request = require('request')
// 通过微信小程序开发文档里面的加密解密下载获取
const WXBizDataCrypt = require('./server/WXBizDataCrypt')

const app = express()
// 小程序开发者获取
const APPID = 'wx2980632cc9eeafd5'
const SECRET = '7890a1d703413e7c39015801ce09f611'
// session标识
const authorization_code = 'demo'

let sessionKey = null
let openid = null

app.get('/onLogin', (req, res) => {
  console.log('reviced')
  const query = req.query
  const { encryptedData, iv, code } = query
  /*
  向微信服务器请求
  获取openid和session_key, 存起来,除非用户失效或者重新登录,不然不会变
  openid一对一,不会变,变的是session_key
  */
  request(`https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${code}&grant_type=${authorization_code}`, (err, response, body) => {
    if (err) console.log(err)
    body = JSON.parse(body)
    // 获取 openid,session_key
    sessionKey = body.session_key
    openid = body.openid
    const pc = new WXBizDataCrypt(APPID, sessionKey)
    // 将加密信息 encryptedData和iv 解密出来
    const data = pc.decryptData(encryptedData, iv)
    res.json(data)
    console.log('send', data)
  })
})
// 如果已经登录了
app.get('/getOpenGid', (req, res) => {
  const query = req.query
  const { encryptedData, iv } = query
  const pc = new WXBizDataCrypt(APPID, sessionKey)
  const data = pc.decryptData(encryptedData, iv)
  res.json(data)
})

小程序码转发

图片生成

客户端向服务端请求 --> 服务端向微信服务器请求 --> 获取二进制图片流 --> 转成png图片存储
--> 返回客户端小程序码的url --> 客户端canvas重新绘制 --> 调用微信api将canvas绘制的存成临时图片
--> wx.getSetting 查询用户是否授权过 --> wx.authorize 询问用户是否授权 --> 使用button组件打开wx.openSetting
--> 调用微信api将临时文件保存到系统相册

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352