前言
微信授权步骤:
- 用户同意授权,获取code。在这一步用户同意授权后,微信会携带
code
参数重定向到redirect_uri
地址上。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
伪代码
@RequestMapping("/getOpenIdStep1")
public String getOpenIdStep1() {
return "redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=encodeURI("xxxx/wxOAuth2Callback")&response_type=code&scope=SCOPE&state=STATE#wechat_redirect "
}
- 用
code
换取access_token
。在这里我们一般会写个接口来接收code
参数,然后使用code
参数去请求微信,如果请求成功微信会给我们access_token
和openId
。
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
伪代码
@RequestMapping("/wxOAuth2Callback")
public String wxOAuth2Callback(String code, HttpSession session) {
response = request( https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=code&grant_type=authorization_code);
// 将openId放入session中
session.setAttribute("openId", response.get("openId"));
return "redirect:xxxx/index";
}
为了方便,我们会在第二步获取的openId
放入session
中,然后其他接口在session
中获取openId
。在线上服务器环境中,其他接口确实可以从session
中获取openId
,但是在线下测试环境session
中获取的openId
为空。
原因
线下环境放入openId
的session
,和取openId
的session
不是同一个session
,为什么会出现这种情况???下面图片是微信回调到本地机器的链路。
由上图可以看到,微信回调的域名是
test.xxx.cn
,浏览器访问的域名是localhost
,这两个请求的域名根本就不一样,因此这两个session
也必定不一样。
解决方案
这里介绍一种暴力解决方案(只适合session已落库-redis,mongo,mysql等)。第一步是浏览器请求,因此,第一步和其他请求(除了微信回调接口)的session
必定是一样,因此只要在第一步的时候加上seessionId
,微信回调后根据seesionId
获取session
,然后将openId
设置到新查出的session
中即可。
伪代码如下:
第一步
@RequestMapping("/getOpenIdStep1")
public String getOpenIdStep1(HttpSession session) {
return "redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=encodeURI("xxxx/wxOAuth2Callback?sessionId=" + session.getId())&response_type=code&scope=SCOPE&state=STATE#wechat_redirect "
}
要点:
redirect_uri=encodeURI("xxxx/wxOAuth2Callback?sessionId=" + session.getId())
第二步
将openId
放入新查的session
中。
@RequestMapping("/wxOAuth2Callback")
public String wxOAuth2Callback(String code, HttpSession session, String seesionId) {
response = request( https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=code&grant_type=authorization_code);
// 将openId放入新查的session中
Session newSession = sessionReporitory.getSession(sessionId);
newSession .setAttribute("openId", response.get("openId"));
sessionReporitory.save(newSession);
return "redirect:xxxx/index";
}
网友评论