7

微信扫描小程序码登录 PC 网站 Demo

 3 years ago
source link: http://xuedingmiao.com/blog/wx_scan_mp_login_demo.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文主要介绍如何基于小程序页面授权,使用微信扫描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 的话,会变得很是方便。
缺点就是万一依附的小程序有什么意外,这个功能就用不了,另外这个适合做成一个插件,这样子就比较通用了。

# 参考资料


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK