项目最重要的需求就是向特定的用户群体推送模板消息,因此需要实现将公众号订阅者的信息与数据库中原有信息进行绑定。但微信公众号的接口并不能直接获取用户的个人信息,因此需要构建一个可以实现用户信息绑定的页面,通过构造网页授权url,然后构成超链接并加入用户填写的信息让用户点击,这样当用户同意授权后,会回调所设置的url并把authorization code和用户填写的信息传过来,然后用这个code获得access token,其中也包含用户的openid信息,从而实现将用户openid与用户填写的信息进行绑定。
微信授权
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@Slf4j
@RequiredArgsConstructor
@Controller
@RequestMapping("/wx/authorize")
public class WxAuthorizeController {
private final WxMpService wxService;
private final WxMpProperties properties;
private final StudentService studentService;
/**
* 请求微信服务器认证授权
* 用户在页面填写需要绑定的信息(手机号)然后调用此接口,会构造一个请求微信服务器认证授权并携带需要绑定信息的超链接,进行重定向
* @param phone 绑定的手机号
* @return 重定向网址
*/
@GetMapping
public String authorize(@RequestParam("phone") String phone) {
// 用户授权完成后的重定向链接,properties.getTestUrl()是项目的公网域名,该域名需要在微信公众号后台配置,否则请求微信服务器不成功,本地测试时一般都是采用将本地服务代理映射到一个可以访问的公网进行开发调试
String url = properties.getTestUrl()+"/wx/authorize/userInfo";
String redirectURL = wxService.getOAuth2Service().buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_USERINFO, URLEncoder.encode(phone));
log.info("【微信网页授权】获取code,redirectURL={}", redirectURL);
return "redirect:" + redirectURL;
}
/**
* 构造请求微信服务器认证授权超链接时需要微信服务器重定向的接口,微信服务器认证授权成功后会自动调用此接口并携带用户wxOAuth2AccessToken信息和之前传入的绑定信息
* @param code 构造用户wxOAuth2AccessToken信息的授权码
* @param phone 用户传入的绑定信息
* @return 重定向绑定之后的链接
*/
@GetMapping("/userInfo")
public String userInfo(@RequestParam("code") String code,
@RequestParam("state") String phone) throws Exception {
log.info("【微信网页授权】code={}", code);
log.info("【微信网页授权】state={}", phone);
WxOAuth2AccessToken wxOAuth2AccessToken;
try {
// 获取accessToken
wxOAuth2AccessToken = wxService.getOAuth2Service().getAccessToken(code);
} catch (WxErrorException e) {
log.error("【微信网页授权】{}", e);
throw new Exception(e.getError().getErrorMsg());
}
// 根据accessToken获取openId
String openId = wxOAuth2AccessToken.getOpenId();
log.info("【微信网页授权】openId={}", openId);
//根据业务逻辑将openId与phone进行绑定
String lang = "zh_CN"; //语言
WxMpUser user = wxService.getUserService().userInfo(openId,lang);
log.info("【微信网页授权】wxMpUser={}", user);
// 获取用户信息
WxOAuth2UserInfo wxUser = wxService.getOAuth2Service().getUserInfo(wxOAuth2AccessToken, null);
log.info("【微信网页授权】wxMpUser={}", wxUser);
// 刷新accessToken
wxService.getOAuth2Service().refreshAccessToken(wxOAuth2AccessToken.getRefreshToken());
// 验证accessToken是否有效
wxService.getOAuth2Service().validateAccessToken(wxOAuth2AccessToken);
//重定向绑定成功的超链接
return "redirect:"+properties.getWebUrl()+"/#/bindSuccess;
}
}