OAuth 的核心
OAuth 的核心就是向第三方应用颁发令牌。OAuth提供了四种获取令牌的授权方式
授权码(authorization-code)、隐藏式(implicit)、密码式(password)、客户端凭证(client credentials)。
而微信登陆采用的是授权码模式。
背景
目前项目大多都是采用前后端分离模式开发。本文前端采用 vue ,后端采用spring boot + spring cloud 实现的一套微服务架构,
采用独立的授权服务器进行网站授权、颁发token。
当然开发微信登陆需要去微信开放平台https://open.weixin.qq.com注册用户,添加网站应用如:
并获取appid、appSecret、redirect_uri。
appid:应用唯一标识微信通过这个id来识别是那个网站应用来访问的。
appSecret:应用接口使用密钥,要严格保密。一般保存在后台服务器上。
redirect_uri:微信开放平台授权回调域,用户扫描二维码并同意授权之后回调的域名。
开发整个流程:
- 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
- 通过code参数加上AppID和AppSecret等,通过API换取access_token、openid;
- 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
开发
一、vue前端页面展示微信二维码(将微信二维码内嵌到我们自己的网站上)
通过阅读微信开放平台上的文档我们了解到。
当需要展示微信二维码时,我们需要实例化一个js对象
var obj = new WxLogin({self_redirect:true,id:"login_container", appid: "", scope: "", redirect_uri: "",state: "",style: "",href: ""});
redirect_uri中的地址需要处理一下的。处理方式:通过JavaScript encodeURIComponent() 函数。
参数说明
当然只实例化这个js对象是无法展示二维码的,我们需要引入微信官方提供的js文件。
在vue的生命周期函数mounted中。
mounted() {const s = document.createElement('script');s.type = 'text/javascript';s.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js';document.body.appendChild(s);},
二、授权回调域
实例化js对象时。我们写了redirect_uri回掉域名。我是将回掉地址放到了前端页面,然后通过回调地址中时候带有code参数来判断,是否向后台发送接口请求(用户拒绝授权时,回掉地址上回没有code参数的)
1、如果回掉地址中带有code则发送后台接口访问。
后台配置文件中添加
使用如下链接:https://api.weixin.qq.com/sns/oauth2/access_tokenappid=%s&secret=%s&code=%s&grant_type=authorization_code
发送一个http请求获取openid、access_token。
然后通过
https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
可以拿到用户的相关信息。
三、前端重定向
用户有可能在不同的页面进行点击登陆,因此当用户登录成功之后需要重定向到用户点击登陆的地址也是非常不错的用户体验。
我采用的是通过Cookie,用户点击登陆时,我就将当前页面的路径保存到Cookie中,然后通过访问后台接口返回的参数来确定用户是重定向到点击登陆页面还是重定向到其他页面。
this. r o u t e . q u e r y : 参 数 。 可 以 获 取 路 径 上 的 参 数 。 t h i s . route.query:参数。可以获取路径上的参数。 this. route.query:参数。可以获取路径上的参数。this.router.push({path: Cookie.get(“loginUrl”),query:{‘type’: 2}}):可以重定向到Cookie保存的路径,query是路径上的参数。
this.$route.path:获取当前路径。
四、微信解除绑定
首先微信开放平台上没有提供相关接口。
我采用的还是绑定那一套,获取用户openid,然后在我们本地上去除绑定即删除用户保存的openid。
五、请求微信接口数据乱码
根据微信提供的接口
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
我们可以获取到用户信息,但是通常情况下数据都是乱码的。
因为微信那边采用的是“ISO-8859-1”编码,而我们一般采用“UTF-8”,编码不统一导致的乱码。
既然问题的原因找到了,那我们就开始解决吧:
通过微信提供的公共接口获取的信息是一个JSON字符串
将JSON字符串通过“ISO-8859-1”解码,然后通过“UTF-8”编码成一个新的JSON字符串,此时就可以解决获取用户信息中文乱码问题。
示例代码:
json = new String(vxUserDetail.getBytes("ISO-8859-1"), "UTF-8");