微信网页授权

上篇文章介绍了如何去做微信网页分享,这篇文章介绍如何去做微信网页授权(非静默授权)

那什么是微信网页授权呢?
运行在微信浏览器上的网页,可以获取微信用户的信息和 openid(用户唯一标识) ,通过 openid 可以方便的进行登录操作

接下来就是微信网页授权流程:

注意:授权有两种方式 静默授权获取用户的基本信息的授权
静默授权:
以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
获取用户的基本信息的授权:
以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息

开发流程:

前端:
1. 跳转 code 页 获取 code
2. 把 code 传递给后端提供的接口
3. 保存接口返回的值(openid/用户基本信息)
4. OK,前端就是这些,是不是很简单
后端:
1. 拿到前端传来的 code
2. 通过 code 获取 access_token、refresh_token、openid
3. 通过 access_token 和 openid 获取 用户的基本信息 city、country、nickname 等等

上述有提到 refresh_token,那它是干什么的?
由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权 (下面的代码中我们就会用这种机制实现)

接下来就上代码吧
注意:
config配置信息与上篇文章一致,代码中缓存用的 redis 也与上篇一致
后端代码:

router.get('/', async ctx => {
  const code = ctx.query.code
  const { appID, appSecret } = global.config.WECHAT_OFFICIAL_ACCOUNT

  let _openid = ''

  // 首先获取 refresh_token
  const refresh_token = await get('refresh_token')
  // 如果 refresh_token 缓存过
  if (refresh_token) {
    try {
      // 通过 refresh_token 刷新 access_token
      const res = await axios({
        url: `https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${appID}&grant_type=refresh_token&refresh_token=${refresh_token}`,
        method: 'GET'
      })
      const { access_token,
              expires_in,
              refresh_token,
              openid } = res.data
      set('access_token_auth', access_token, expires_in)
      set('refresh_token',  refresh_token)
      _openid = openid
    } catch (error) {
      // refresh_token 有30天有效期,若过期重新通过 code 获取 access_token
      const res = await axios({
        url: `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appID}&secret=${appSecret}&code=${code}&grant_type=authorization_code`,
        method: 'GET'
      })
      const { access_token,
              expires_in,
              refresh_token,
              openid} = res.data

      _openid = openid
      set('access_token_auth', access_token, expires_in)
      set('refresh_token', refresh_token)
    }
  } else {
    // 如果 refresh_token 不存在,通过 code 获取 access_token(其实这个与上部分refresh_token过期时逻辑一样)
    const res = await axios({
      url: `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appID}&secret=${appSecret}&code=${code}&grant_type=authorization_code`,
      method: 'GET'
    })
    const { access_token,
            expires_in,
            refresh_token,
            openid} = res.data
    _openid = openid
    set('access_token_auth', access_token, expires_in)
    set('refresh_token', refresh_token)
  }

  const access_token = await get('access_token_auth')
  // 获取用户的基本信息
  const res_userinfo = await axios({
    url: `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${_openid}&lang=zh_CN`,
    method: 'GET'
  })

  // 返回给前端 openid 与 用户基本信息
  ctx.body = {
    openid: _openid,
    ...res_userinfo.data
  }
})

前端代码:

  let search = location.search
  let obj = {}
  if (search.indexOf('?') !== -1) {
    let str = search.substr(1)
    let strArr = str.split('&')
    strArr.forEach(item => {
      let [key, value] = item.split('=')
      obj[key] = value
    })
  }
  if (obj.code) {
    // 通过 code 获取用户 openid 与 userinfo
    $.ajax({url: '/auth?code='+obj.code, success: res => {
      console.log('这里就能获取到接口返回的openid 与 用户信息', res);
    }})
  } else {
    // 跳转 code 页获取code
    let href = encodeURI(location.href)
    location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?'
            +'appid=' + '你的APPID'
            +'&redirect_uri=' + href
            +'&response_type=code&scope=snsapi_userinfo#wechat_redirect'
  }
讨论数量: 1

特地过来看下一集!

4年前

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!