微信授权登陆流程(vue+SpringMVC)
这几天微信公众号网页项目前后端对接到最后阶段,差微信授权登录就基本完成,结果卡了几天,总算解决。对于微信公众平台文档,一定要认真细读,这里就挑重点说下【文档传送门】。1 第一步:用户同意授权,获取code2 第二步:通过code换取网页授权access_token3 第三步:刷新access_token(如果需要)4 第四步:拉取用户信息(需scope为 snsapi_...
这几天微信公众号网页项目前后端对接到最后阶段,差微信授权登录就基本完成,结果卡了几天,总算解决。
对于微信公众平台文档,一定要认真细读,这里就挑重点说下【文档传送门】。
1 第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
1 第一步:用户同意授权,获取code
这里获取code,是由前端引导用户实现获取。微信提供的获取方式是
参考链接(请在微信客户端中打开此链接体验):
scope为snsapi_base
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect
scope为snsapi_userinfo
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
现在说下如何引导?
参看OAuth流程的时候,也看到 引导
这个词,具体如何引导,一开始我做的处理是后台使用SpringMVC拦截所有请求,如果没有授权的则在后台使用如上链接获取code,最终返回一个token给前端。
问题恰恰出现在这里,直接返回token给前端时,因为微信授权需要重定向,异步请求无法处理重定向,所以只能主动跳转,而主动跳转后前端拿到了token,却无法继续访问原先的请求。(因为是后端拦截后做的跳转)
于是翻阅了网上很多关于Oauth的博客,在这如何 引导
用户进入授权流程上却没有明确说明(更主要是我悟性太低),终于在github上一个开源项目找到了。他做的处理是在首页打开时就判断cookie中是否存在token,如果没有则由前端主动跳转到授权页面,也就是重定向到上面微信获取code的链接。
部分vue示例代码如下:
created() {
//如果url里有token, 设置进cookie
var token = this.$route.query.token;
if(typeof token !== 'undefined') {
var exp = new Date();
exp.setTime(exp.getTime() + 3600 * 1000);//过期时间60分钟
document.cookie = 'token=' + token + ";expires=" + exp.toGMTString();
}
//获取token,前端主动跳转到微信获取code的链接——tokenUrl,这里最好由后端封装好一个接口,不要直接暴露整个链接。
//returnUrl是传给后端用来跳转回前端页面的地址
if(getCookie('token') == null) {
location.href = config.projectUrl + '/auth?returnUrl=' + encodeURIComponent(config.projectUrl + '/#/');
}
后台封装的接口
@RequestMapping("/auth")
public String auth(String returnUrl, HttpServletResponse response) throws IOException {
return "redirect:" +
String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect",
this.wxAppId, URLEncoder.encode(this.wxRedirectUri), "snsapi_userinfo", returnUrl);
}
2 第二步:通过code换取网页授权access_token
那么如何获取后的code怎么拿到呢?这里要提到微信获取code链接传参中有一个 redirect_uri
,这就回调地址就是用来接收code的,现在后端需要提供一个接口如 /login
,于是redirect_uri可以写成 项目地址/login
,此外需要要encode转下编码。
部分Java示例代码如下:
@RequestMapping("/login")
public String login(
@RequestParam(name="code") String code,
@RequestParam(name="state", required=false) String state,
HttpServletResponse servletResponse
) {...}
可以注意到方法签名中多了state这个形参,在 /auth
接口的方法中将前端传的returnUrl作为state的值传过来。
微信定义state:重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节
所以我们利用这个state来传跳回前端页面的地址。
现在拿到code了,可以换access_token,取到用户信息了
String accessToken = httpRequest.doGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid="+APPID+"&secret="+APPSRECT+"&code="+code+"&grant_type=authorization_code");
3 第三步:刷新access_token(如果需要)
因为access_token很快过期,所以利用数据库和redis存储access_token,需要时查询数据库获取即可。
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
拿到access_token后,利用Gson获取阿里的JSON转成对象就可以获取用户信息了。
这里后端用redis生成100分钟的token返回给前端,同时用上述提到的state重定向回到前端页面,前端一拿到token就可进行存cookie的处理,以后每次请求头中带token便可通过认证了。
return "redirect:" + state + "?token=" + token;
项目地址:https://github.com/hdonghong/mrkt
若项目对您有所帮助,还请给个star或者赞,这是对我最大的鼓励。
更多推荐
所有评论(0)