前言
微信授权步骤:
- 用户同意授权,获取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";
}











网友评论