【附源码】微信公众号 h5 网页授权开发

一. 前言

在微信公众号开发中,常常需要使用 h5 页面公众号的授权登录,获取 jscode、openid 等,以便进一步获取用户的开放信息等,和我们系统中的真实用户做绑定。

由于授权登录开发的业务流程,大多都是微信公众号开发的第一步,所以本篇文章将使用最简洁快速的方式实现一个微信公众号 h5 授权获取 openid 流程,并附源码供大家参考!

二. 准备工作

在正式调试之前,确保你的微信公众号已经具备了以下条件:

  • 已经是认证的服务号或订阅号(一般为服务号)。

  • 在微信公众平台配置了合法的域名。

  • 拥有开发者权限,能够访问微信公众平台的接口文档和开发工具。

开发调试阶段

然而,在开发调试,我们可以通过微信公众平台测试账号来进行调试,只需要简单配置即可获取调用微信的接口权限。

通过微信公众平台测试账号,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。

通过微信公众平台测试账号连接配置测试账号进行开发调试!

登录成功后通过以下流程进行简单配置:

  1. 设置 JS 接口安全域名
  1. 扫描关注
  1. 设置授权回调域名

设置完成上面的流程即可以进行开发调试了,如果使用该方式可以调试成功,那么在正式公众号配置正确后也会没有问题。

如果是正式的已经获得权限的公众号,可以在相应的微信公众平台->开发接口管理->基本配置中设置

三. 授权流程

微信 h5 授权登录主要分为以下几个步骤:

1. 引导用户进入授权页面

首先,按照微信公众号的授权流程,构造一个标准 URL 来引导用户进入微信授权页面。该 URL 的格式如下:

js 复制代码
https://open.weixin.qq.com/connect/oauth2/authorize?
appid=APPID&redirect_uri=REDIRECT_URI&response_type=code
&scope=SCOPE&state=STATE#wechat_redirect

下面对其中的参数含义解释:

  • APPID 是你的公众号的 AppID。

  • REDIRECT_URI 是授权后重定向的回调链接地址,必须要进行 URL 编码,很重要。

  • SCOPE 授权作用域,snsapi_base(静默授权,不弹出授权页面,直接跳转,只能获取用户 openid),snsapi_userinfo(弹出授权页面,可通过 openid 拿到昵称、性别、所在地等信息)。

  • STATE 用于保持请求和回调的状态,授权请求后原样带回给第三方。

在这里,我主要获取用户的 openid,所以使用的是静默授权,即 snsapi_base 作用域。

2. 用户同意授权

用户进入链接后会被重定向到微信授权页面,如果用户同意授权,则会被重定向回你设置的 REDIRECT_URI,并携带一个 code 参数。

3. 通过 code 换取网页授权 access_token

获取到 code 后,可以调用微信接口,用 code 换取网页授权 access_token。API 如下:

bash 复制代码
https://api.weixin.qq.com/sns/oauth2/access_token?
appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

其中:

  • APPIDSECRET 是你的应用 ID 和应用密钥。

  • CODE 上一步中获得的 code。

成功响应示例如下:

json 复制代码
{
  "access_token": "ACCESS_TOKEN",
  "expires_in": 7200,
  "refresh_token": "REFRESH_TOKEN",
  "openid": "OPENID",
  "scope": "SCOPE"
}

4. 拉取用户信息(可选)

如果在第一步选择了 snsapi_userinfo 作为 scope,那么可以通过获取到的 access_tokenopenid 来调用接口获取用户的基本信息。API 如下:

ini 复制代码
https://api.weixin.qq.com/sns/userinfo?
access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

注意:第 3 步和第 4 步为了说明,直接在前端代码中进行了演示,实际开发中为了安全性考虑,应将这两步放在后端进行请求。

四. 可能出现的问题

redirect_uri 参数错误

在开发调试过程中,最常出现的错误就是 redirect_uri 参数错误

出现这个问题一般有两个原因:

  1. redirect_uri 没有使用编码处理,需要使用 encodeURIComponent 编码处理
js 复制代码
getRedirectUri(url) {
  url = url || window.location.href
  const pos = url.indexOf('?')
  if (pos > -1) {
    return encodeURIComponent(url.substring(0, pos))
  }
  console.log(url)
  return encodeURIComponent(url)
}
  1. OAuth2.0 网页授权,授权回调页面域名填写不正确,按照以下方式填写正确即可

一般的,通过以上两步可以解决 redirect_uri 参数错误的问题

五. 注意事项

  • 安全性考虑,不要将 secret 等敏感信息暴露在前端代码中,因此前端在获取到 jscode 后可调用后台接口获取 openid 和用户信息。

  • code的有效期较短,通常为 5 分钟,因此需要尽快使用。

  • 正式授权过程中,回调地址必须是已注册的域名下的链接,否则无法成功授权。

  • 在开发过程中,建议使用微信公众平台提供的测试账号进行调试,以减少对正式环境的影响。

  • 使用 Vue 开发时,建议使用 history 路由模式,避免微信回调链接的参数拼接问题

  • redirect_uri 必须使用 encodeURIComponent 进行编码处理

通过上述步骤,你可以顺利地在微信公众号中实现 h5 页面的授权获取到 openid,从而实现用户信息的获取和后续操作。

六. 文档链接

微信公众号网页授权文档

源码

复制以下工具类wxh5.js到自己项目中,在需要授权的页面中调用即可。

js 复制代码
import wxh5 from './wxh5'
// 在需要授权的地址,调用方法初始化微信授权,test为appids中的key
wxh5.init('test')

wxh5.js 工具类

js 复制代码
// 微信公众号appid管理,可加入多个,维护自己的appid
const appids = {
  test: 'wx0c5aacb245636f69',
  test2: 'wx1bfaa45b867d8b62'
  // ... 更多的appid等
}
const scope = 'snsapi_base' // 微信授权scope
const state = 'state' // 微信授权state

// 获取微信授权回调url
export function getRedirectUri(url) {
  url = url || window.location.href
  const pos = url.indexOf('?')
  if (pos > -1) {
    return encodeURIComponent(url.substring(0, pos))
  }
  return encodeURIComponent(url)
}

// 解析url参数
export function getUrlParam(name) {
  var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
  var r = window.location.search.substr(1).match(reg)
  if (r != null) return unescape(r[2])
  return null
}

export default {
  // 初始化
  init(appType) {
    const jscode = getUrlParam('code') // 获取url中的code
    console.log('获取到jscode:', jscode)
    if (!jscode) {
      this.auth(appType)
    }
  },
  // 微信授权
  auth(platform) {
    const appid = appids[platform]
    if (!appid) {
      alert('获取 appid 有误,请先维护 appid!')
      return
    }
    const baseUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize'
    const url = `${baseUrl}?appid=${appid}&redirect_uri=${getRedirectUri()}&response_type=code&scope=${scope}&state=${state}&connect_redirect=1#wechat_redirect`
    window.location.replace(url)
  },
  // 是否为微信内置浏览器
  isWeixin() {
    return typeof WeixinJSBridge === 'object' && typeof WeixinJSBridge.invoke === 'function'
  },
  // 关闭当前微信浏览器窗口
  closeWindow() {
    if (WeixinJSBridge) {
      try {
        WeixinJSBridge.call('closeWindow')
      } catch (error) {}
    }
  }
}
相关推荐
sunly_32 分钟前
Flutter:flutter_screenutil屏幕适配
前端·javascript·flutter
俸涛努力学前端37 分钟前
ajax (一)
开发语言·前端·javascript·笔记·ajax
凌虚(失业了求个工作)1 小时前
Web 端语音对话 AI 示例:使用 Whisper 和 llama.cpp 构建语音聊天机器人
前端·人工智能·python·whisper·llama
信息化未来1 小时前
odoo17 档案管理之翻译2
java·服务器·前端
川石课堂软件测试1 小时前
UI自动化测试|web端元素获取&元素等待实践
开发语言·前端·功能测试·算法·ui
糯米w1 小时前
【前端】excel文件对比
前端·javascript·excel
南城巷陌1 小时前
node.js中实现router模块化管理
前端·javascript·node.js·express.router
new Vue()2 小时前
ES6中Promise的使用场景
开发语言·前端·javascript
Mr.Liu62 小时前
小程序-使用 iconfont 图标库报错:Failed to load font
前端·微信小程序·小程序
Mr.Liu62 小时前
小程序25- iconfont 字体图标的使用
前端·微信小程序·小程序