微信网页授权
上篇文章介绍了如何去做微信网页分享,这篇文章介绍如何去做微信网页授权(非静默授权)
那什么是微信网页授权呢?运行在微信浏览器上的网页,可以获取微信用户的信息和 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'
}
特地过来看下一集!