微信的网页授权是指在微信公众号获取用户个人信息等一些权限.这次我们将使用node+express实现一个微信授权功能。
准备工作
- 如果没有域名的话,现在我是通本地
host
文件配置一个域名,只适合局域网测试专用。C:\Windows\System32\drivers\etc
- 我们使用vue快速搭建一个H5页面,vue.config.js一些简单的配置,前端做跨域处理
module.exports = {
lintOnSave: false,
devServer: {
host: "m.imooc.com",
port: 8080, // 端口号
https: false, // https:{type:Boolean}
open: true, //配置自动启动浏览器
proxy: {
"/api": {
//代理api
target: "http://localhost:3000", //服务器api地址
ws: false, // proxy websockets
changeOrigin: false //是否跨域
}
}
}
};
- 在这里我们使用的是微信公众号测试号的
appID
和appsecret
- 测试号网址 ```http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index````
- 测试号二维码 需要开发人员扫码二维码认证一下。得到权限
- 网页帐号 网页授权获取用户基本信息点击修改 填写授权回调页面域名
- 如果是有端口号的话一定要填写端口号
- JS接口安全域名 – 网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等
微信授权流程
- 用户同意授权,获取 code
- 通过 code 换取网页 access_token
- 拉取用户信息(需 scope 为 snsapi_userinfo)
- 关于网页授权的两种scope的区别说明
- 以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
- 以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
开发后端接口
- 使用express快速搭建一个框架,这里就不做讲解,博客文章中也有写到
- 需要安装两个插件request 请求接口,memory-cache存储机制,相当于redis差不多
let request = require('request')
let cache = require('memory-cache')
- config文件我是定于的一些测试号的appID和appSecret
重定向
- 当用户打开网页时,查看是否授权,没有每天授权,重定向到授权页面,否则回到当前页面
//redirectUrl 授权回调地址,从客户端返回的地址
//callback 获取openId 用户点击授权,调用这个
router.get('/redirect', function (req, res) {
let redirectUrl = req.query.url,
scope = req.query.scope,
callback = 'http://m.imooc.com:8080/api/wechat/getOpenId'
cache.put('redirectUrl', redirectUrl)
let authorizeUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.appId}&redirect_uri=${callback}&response_type=code&scope=${scope}&state=STATE#wechat_redirect`
res.redirect(authorizeUrl)
})
根据code获取用户的openId
router.get('/getOpenId', async function (req, res) {
let code = req.query.code
if (!code) {
res.json({
code: 1001,
data: '',
message: '当前未获取到code码',
})
} else {
// 拿到用户openId
let token_url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${config.appId}&secret=${config.appSecret}&code=${code}&grant_type=authorization_code`
request.get(token_url, function (err, response, body) {
console.log(body)
if (!err && response.statusCode == '200') {
let data = JSON.parse(body)
if (data && !data.errCode) {
let expire_time = 1000 * 60 * 60 * 2 //过期时间
cache.put('access_token', data.access_token, expire_time)
cache.put('openId', data.openId, expire_time)
res.cookie('openId', data.openid, {
maxAge: expire_time,
}) //存储openId
let redirectUrl = cache.get('redirectUrl')
res.redirect(redirectUrl)
} else {
res.json({
code: data.errcode,
data: '',
message: data.errmsg,
})
}
} else {
res.json({
code: 1009,
data: '',
message: err,
})
}
})
}
})
获取用户信息
- 通过获取用户openID就可以拿到用户信息。
router.get('/getUserInfo', function (req, res) {
let access_token = cache.get('access_token')
let openId = cache.get('openId')
let userinfo = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${openId}&lang=zh_CN`;
request.get(userinfo, function (err, response, body) {
if (!err && response.statusCode == '200') {
let data = JSON.parse(body)
if (data && !data.errCode) {
console.log(data, 'dadsd')
res.json({
code: 200,
data,
message: '获取用户信息成功'
})
} else {
res.json({
code: data.errcode,
data: '',
message: data.errmsg,
})
}
} else {
res.json({
code: 1009,
data: '',
message: err,
})
}
})
})
H5页面
- 在App.vue页面中,判断cookie是否有openID,如果没有,跳转授权页面
跳转页面接口
let openId = this.$cookie.get('openId')
if (!openId) {
window.location.href =' /api/wechat/redirect?url=http%3A%2F%2Fm.imooc.com%3A8080%2F%23%2Findex&scope=snsapi_userinfo'
}
- 获取用户信息
getUserInfo() {
this.$http.get(API.getUserInfo).then((response) => {
let res = response.data
console.log(JSON.stringify(res))
this.userInfo = res.data
})
},