本文主要介绍如何基于小程序页面授权,使用微信扫描PC端小程序码实现获取用户信息进行系统登录。

之前介绍过一个Demovue项目:基于网页授权的微信扫码登录Demo,最近了解到小程序也可以实现这个功能,所以突发奇想自己实现一个备用吧。

# 实现思路

简要介绍

PC 端点击使用小程序登录时会生成一个 uuid 并弹出一个小程序码,小程序码的 scene 值附带了生成的 uuid 对应到一个线上的小程序页面,微信扫码后打开小程序页面,小程序内解析 scene 值中的 uuid ,用户点击按钮进行授权登录,页面内拿到用户信息后通过云函数将 uuid 及 用户信息传递给服务端后存入云数据库中,PC 端通过轮询方式根据打开页面时生成的 uuid 作为参数来获取用户的 openid 等基础信息进行登录操作从而进入系统。

# 使用技术栈

主要技术介绍:

  • vue:2.6.11
  • vuex:3.1.2
  • vue-router:3.1.5
  • element-ui:2.13.0
  • koa:2.11.0
  • 小程序云开发

# 主要问题

  1. 小程序全局 access_token
    项目需要在 web 端生成小程序码,二维码生成需要小程序全局 access_token,所以选择了在打开页面的时候预生成全局 access_token 以备用
  2. 小程序码更新问题
    本示例项目的小程序页面授权获取信息采用了两种方式
  • 云端免鉴权:用户扫码打开小程序页面时就利用云函数获取到用户的 openid 信息
  • 按钮获取:通过用户主动点击授权按钮获取开放数据,包含昵称、头像数据
    两种处理方式不同,所以生成的小程序码的 scene 值也是不同的,用户切换两种方式的时候需要实时更新二维码

# 项目开发

# 服务端启动

服务端基于 koa 框架开发,在根目录的 server 文件夹下。

安装依赖

cd server
npm install

配置小程序,复制一份 config.sample.js 重命名为 config.js 填好如下配置

module.exports = {
  port: '', // 服务端端口号
  appId: '', // 小程序appid
  appSecret: '' // 小程序secrect
}

然后启动服务

node app.js

访问地址

http://localhost:2002

接着我们来配置 web 端

# web 端

修改env环境变量配置,项目使用的后台服务端口为 2002

VUE_APP_BASE_API = 'http://localhost:2002'

安装依赖

npm install

开发

npm run serve

访问

http://localhost:9556

web 端默认使用9556端口

# 小程序修改

项目的主角是小程序,所以当然需要一个小程序,个人主体就可以。
有了小程序之后首先要在微信开发者工具内开通云开发。
接着进行下面的操作。

  1. 新建云函数 例:openid_login
    作用主要是为了获取用户信息并存入云数据库
    index.js 内容:
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()

exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  try {
    let openid = wxContext.OPENID
    // 防止重复存储
    let uuids = await db
      .collection('uuids')
      .where({
        uuid: event.uuid,
      })
      .get()

    if (uuids.data.length) {
      await db
        .collection('uuids')
        .doc(uuids.data[0]._id)
        .update({
          data: {
            openid: openid,
          },
        })
      return uuids
    }

    const result = await db.collection('uuids').add({
      data: {
        ...event,
        uuid: event.uuid,
        openid: openid,
      },
    })
    return result
  } catch (err) {
    console.log(err)
    return err
  }
}

package.json 内容:

{
  "name": "openid_login",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "wx-server-sdk": "latest"
  }
}
  1. 在云数据库新建一个集合,比如 uuids,主要为了存储 uuid 以及用户信息的。

  2. 新建一个小程序页面,扫码登录用的。
    这里我是用的个人博客小程序,框架用的 mpvue ,下面是核心代码。

onLoad(options) {
  let params = []
  // 扫码进来时的处理
  if (options.scene) {
    params = decodeURIComponent(options.scene).split('&')
    this.uuid = params[0].split('=')[1]
    this.useAuth = params[1].split('=')[1]
  } else {
    this.uuid = options.uuid
    this.useAuth = options.useAuth
  }
  if (+this.useAuth === 0) {
    wx.cloud.callFunction({
      name: 'openid_login',
      data: {
        uuid: this.uuid,
      },
    })
  }
},

需要注意的是小程序码里对应的页面必须是线上的页面,所以要审核通过之后才能进行测试。

# 在线 Demo

可以用这个来体验一下扫描小程序码登录的有趣玩法。http://mpscan.tiaocaoer.com

# 项目总结

一个字:有意思。
首先又可以多拉几个用户了,用户每次登录都需要扫码二维码,无形当中增加了很多日活啊,妙哉~
另外巧妙运用了云开发的免鉴权,如果只是需要 openid 或者 unionid 的话,会变得很是方便。
缺点就是万一依附的小程序有什么意外,这个功能就用不了,另外这个适合做成一个插件,这样子就比较通用了。

# 参考资料

Logo

前往低代码交流专区

更多推荐