微信网页静默授权

8,628 阅读4分钟

前言

用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。接下来了解下如何实现微信网页静默授权。

微信开发前配置

为了帮助开发者快速了解和上手微信公众号开发,熟悉各个接口的调用,我们推出了微信公众帐号测试号,通过手机微信扫描二维码即可获得测试号。 进入微信公众帐号测试号申请系统

开发微信网页授权功能必须有服务号(针对与企业),个人只能申请订阅号。但是我们可以通过申请接口测试号来完成功能开发。

打开测试号管理页面,提供的测试号信息 appID 和 appsecret 。需要我们提供可用域名验证服务器资源可用。

具体做法就是:

  1. 在接口配置信息中填写你的服务器地址,Token(自定义随意写)
  2. 微信服务会发送一个请求给你的服务器会带上一系列参数,要求你返回对应的参数
// 服务端代码如下 
// 获取 测试号管理微信号 token
router.get('/token',async ctx=>{
  const token = 'customToken'
  const {
    signature,
    timestamp,
    nonce,
    echostr
  } = ctx.query
  // 进行字典排序加密
  let str = [token, timestamp, nonce].sort().join("");
  let sha = sha1(str)
  // 校验微信加密签名,返回echostr内容
  if (sha === signature) {
    ctx.body = echostr
  } else {
    ctx.body = "wrong"
  }
})

服务器验证成功后扫测试号二维码添加用户列表后就可以开始开发了。

开发步骤

投放链接格式

在服务号中投放链接格式如下(手动拼接的):

open.weixin.qq.com/connect/oau…

需要注意的是

  1. redirect_uri 地址的域名需要和 js接口安全域名对应。

  2. scope 应用授权作用域:snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。

通过 code 换取网页授权 access_token

本身 redirect_uri 重定向的链接中是没有 code ,当我们在微信浏览器中打开投放的链接是,微信会自动跳转到目标地址,并且在链接后拼接上 code 值。为了方便查看,我将上面链接在微信开发者工具中打开得到链接如下。

客户端获取到链接中到 code 将其传递给服务端。服务端代码如下,调用 https://open.weixin.qq.com/connect/oauth2/authorize 并将相关参数传递给微信服务器拿到 access_token

router.get('/access-token',async ctx=>{
  const grant_type = 'authorization_code'
  const code = ctx.query.code 
  // 拿到 access_token
  let wechatInfo = await fetchGet('/oauth2/access_token',{
    appid,
    secret,
    code,
    grant_type
  })
  console.log('wechatInfo',wechatInfo);
  // {"access_token":"28_pC4LZEoIa2boBlUlT2X3itT_yDAzrwiPXgqbxEAgf2XC7Eye2jHj3_WW4Xqf8ra0b-gPaCIC6bmiuS5O_VMQ4g","expires_in":7200,"refresh_token":"28_m5hfO9IYieZKJUCU7I_0LzJMdfFLmO10nX0IHiBEkW63yNTy2XBJS2wvke1uISSrKbsS9f3n7PpEjRRQgjl8CA","openid":"oNqRVxFO4TCF0CehAJfWGJI_kU14","scope":"snsapi_base"}
})

获取用户信息

如果 scope 为 snsapi_userinfo 在用户授权了以后,会跳转到 redirect_uri 的地址,服务端请求 connect/oauth2/authorize 接口后拿到 access_token 和 openid 。接下来通过这两个参数去拉取用户信息。

const { access_token,refresh_token,openid } = wechatInfo
let userinfo = await fetchGet('/userinfo',{
  access_token,
  openid,
  lang:'zh_CN'
})
console.log('userinfo',userinfo);
// {"openid":"oNqRVxFO4TCF0CehAJfWGJI_kU14","nickname":"浼氶","sex":0,"language":"zh_CN","city":"","province":"","country":"","headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/QpnatTdwxlVfGO1ZdZYlACghRbXhq8sibI2GF8x0XhVqcmPKl7OQxI5wOobHiaiblOr0kaojXLGbicibc8pa8zk2wPg\/132","privilege":[]}

校验 access_token 是否有效 和 刷新 access_token

通过该接口来判断 access_token 的有效性

https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID

如需刷新 access_token 将之前 /oauth2/access_token 接口返回的 refresh_token 作为参数去调刷新的接口拿最新的接口

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

"errcode":40163,"errmsg":"code been used

code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

如果使用相同的 code 调用 connect/oauth2/authorize 接口后面会报这个错误。

注意点

如果用户关注过公众号后只需通过 openid 即可去拉取用户的信息

• 针对从公众号入口进入的用户采用静默授权的方式

• 用法通过复制链接分享,或者二次分享的形式那么获得的用户可能未关注过公众号,想要拿到他们链接需要弹框授权。

code 无效情况

• 静默授权后需要将链接中的code处理调否则会导致 code 重复使用造成无效的报错。

    const url = location.href.replace(/code=\w+&/g,'')
        history.replaceState(history.state,document.title,url)

二次分享link设置 需要跟微信后台设置点安全域名列表中保持一致

• 二次分享时 link 无法直接分享 open.weixin.qq.com/... 的地址,其次的解决方式是,判断链接中是否存在 code 如果不存在使用 location.href = url 的方式直接跳转我们拼接好的 open.weixin.qq.com/... 但是会造成页面一闪的情况,交互体验不好。

• 引发的负作用就是如果一个页面使用code授权到了第二个页面,在第一个页面已经将code处理掉,又会重新去通过 location.href 强刷一下页面,这里需要考虑使用 keep-alive 来处理。

• 链接中传参数不稳定,如果在后续页面添加参数在链接中由于 返回到首页会导致页面强制刷新,可以考虑将参数存在本地

微信官方文档