微信公众号测试账号页面申请测试账号
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
第一步:填写服务器配置
URL
http://*******************/wechatLogin/checkSignature
Token
hello
配置授权回调页面域名
体验接口权限表 --> 更多操作网页服务 --> 网页帐号 --> 网页授权获取用户基本信息
houhouhou.nat100.top
第二步:验证消息的确来自微信服务器
/**
* 验证服务器地址的有效性
*/
@Value("${wechat.TOKEN}")
private String TOKEN;
//wechat:
// TOKEN: hello #接口配置信息的TOKEN
@GetMapping("/checkSignature")
public String checkSignature(@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr){
String[] params = new String[]{nonce,timestamp,TOKEN};
Arrays.sort(params);
String signatureResult = DigestUtils.sha1Hex(params[0]+params[1] + params[2]);
//校验签名
if(!signatureResult.equals(signature)) {
throw new RuntimeException("signature is not the same wechat signature is " + signature + " signatureResult is " + signatureResult);
}
return echostr;
}
第三步:依据接口文档实现业务逻辑
控制层
@RestController
@RequestMapping("/wechatLogin")
public class WechatLoginController {
@Autowired
WechatLoginService wechatLoginService;
/**
* 生成用户同意授权页面url
*
* @return
*/
@GetMapping("/authorize")
public String getRequestCodeUrl() {
return wechatLoginService.getRequestCodeUrl();
}
/**
* 微信用户登陆
* @param code
* @return
*/
@GetMapping("/login")
public AjaxResult login(@RequestParam("code") String code) {
return AjaxResult.success(wechatLoginService.login(code));
}
//
/**
* 验证服务器地址的有效性
*/
private static final String TOKEN = "wl123";
@GetMapping("/checkSignature")
public String checkSignature(@RequestParam(value = "signature") String signature,
@RequestParam(value = "timestamp") String timestamp,
@RequestParam(value = "nonce") String nonce,
@RequestParam(value = "echostr") String echostr){
String[] params = new String[]{nonce,timestamp,TOKEN};
Arrays.sort(params);
String signatureResult = DigestUtils.sha1Hex(params[0]+params[1] + params[2]);
//校验签名
if(!signatureResult.equals(signature)) {
throw new RuntimeException("signature is not the same wechat signature is " + signature + " signatureResult is " + signatureResult);
}
return echostr;
}
}
服务层
@Configuration
public class HTTPConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
}
@Service
public class WechatLoginService {
@Autowired
RestTemplate restTemplate;
@Value("${wechat.appid}")
private String appid;
@Value("${wechat.appsecret}")
private String secret;
@Value("${wechat.redirectUri}")
private String redirectUri;
//redirectUri: http://********************/wechatLogin/login
/**
* 用户同意授权页
* @return返回code字符串
*/
public String getRequestCodeUrl() {
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromUriString("https://open.weixin.qq.com/connect/oauth2/authorize");
urlBuilder.queryParam("appid",appid)
.queryParam("redirect_uri", redirectUri)
.queryParam("response_type","code")
.queryParam("scope","snsapi_userinfo")
.queryParam("state","xxxx_state");
return urlBuilder.toUriString().concat("#wechat_redirect");
}
/**
* 微信用户登录
* @param code 用户同意授权返回的code
* @return
*/
public WxUserInfo login(@RequestParam("code") String code) {
// 1.获取 access_token
WXAccessToken wxAccessToken = this.getAccessToken(code);
//2.拉取微信用户信息
WxUserInfo wxUserInfo = this.getWxUserInfo(wxAccessToken.getAccess_token(), wxAccessToken.getOpenid());
return wxUserInfo;
}
/**
* 获取 access_token
* @param code
* @return
*/
public WXAccessToken getAccessToken(@RequestParam("code") String code){
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromUriString("https://api.weixin.qq.com/sns/oauth2/access_token");
urlBuilder.queryParam("appid",appid)
.queryParam("secret",secret)
.queryParam("code",code)
.queryParam("grant_type","authorization_code");
URI uri = URI.create(urlBuilder.toUriString());
System.out.println(uri.toString());
String resultStr = restTemplate.getForObject(uri, String.class);
System.out.println("=====================resultStr==============");
System.out.println(resultStr);
return JSONObject.parseObject(resultStr, WXAccessToken.class);
}
/**
* 拉取微信用户信息
* @param accessToken
* @param openid
* @return
*/
public WxUserInfo getWxUserInfo(String accessToken,String openid){
UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromUriString("https://api.weixin.qq.com/sns/userinfo");
urlBuilder.queryParam("access_token",accessToken)
.queryParam("openid",openid)
.queryParam("lang","zh_CN");
URI uri = URI.create(urlBuilder.toUriString());
String resultStr = restTemplate.getForObject(uri, String.class);
System.out.println("=====================resultStr==============");
System.out.println(resultStr);
return JSONObject.parseObject(resultStr, WxUserInfo.class);
}
}
实体类
public class WXAccessToken {
/**
* 网页授权接口调用凭证
*/
private String access_token;
/**
* access_token接口调用凭证超时时间,单位(秒)
*/
private String expires_in;
/**
* 用户刷新access_token
*/
private String refresh_token;
/**
* 用户唯一标识
*/
private String openid;
/**
* 用户授权的作用域,使用逗号(,)分隔
*/
private String scope;
}
======================================
public class WxUserInfo {
/**
* 用户的唯一标识
*/
private String openid;
/**
* 用户昵称
*/
private String nickname;
/**
* 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
*/
private String sex;
/**
* 用户个人资料填写的省份
*/
private String province;
/**
* 普通用户个人资料填写的城市
*/
private String city;
/**
* 国家,如中国为CN
*/
private String country;
/**
* 用户头像
*/
private String headimgurl;
/**
* 用户特权信息
*/
private String[] privilege;
/**
* 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段
*/
private String unionid;
}