效果如下图:
准备工作:
首先我们要申请一个公众号测试账号,公众号平台这里进入并登录即可看到测试账号。
关注公众号,如果不关注授权登录时会提示你关注。
修改网页授权回调域名
主要流程:
2 第二步:通过code换取网页授权access_token
3 第三步:拉取用户信息(需scope为 snsapi_userinfo)
参考官方文档:
具体代码:
新建一个常量类存放微信公众号相关常量
package com.jch.mng.constant;
/**
* 微信小程序常量
* Created by xxs on 2021/7/9 8:45
*/
public class WeChatConstants {
//xxs测试公众号
public static final String appId = "wx8d1eab965e66105a";
public static final String secret = "8e9bc82ce46195795a8a5950859679b4";
/**获取access_token地址*/
public static final String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?";
/**根据code获取access_token地址*/
public static final String getAccessTokenByCodeUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?";
/**刷新token地址*/
public static final String getRefreshTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?";
/**获取用户信息地址*/
public static final String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?";
/**授权回调地址
*请求获取code的回调地址
* 用线上环境的域名或者用内网穿透,不能用ip*/
public static final String callBackUrl = "http://xxs.free.idcfengye.com/author/api/wxAuth/callBack";
// public static final String callBackUrl = "http%3A%2F%2Fwuruyang.free.idcfengye.com%2FwxFunction%2Fcallback";
/**授权获取到用户信息后重定向回公众号页面*/
public static final String redirectPageUrl = "http://xxs.free.idcfengye.com/";
}
调试公众号用到的接口
/**
* TODO
* Created by xxs on 2021/7/8 11:50
*/
public class WXAuthUtil {
private static Logger logger = LoggerFactory.getLogger(WXAuthUtil.class);
/**
* @Description: 获取access_token
* @Param: []
* @Author: xxs
* @Date: 2021/7/8 17:19
*/
public static String getAccessToken(){
String result= HttpUtil.get(WeChatConstants.getAccessTokenUrl+"grant_type=client_credential&appid="+ WeChatConstants.appId+"&secret="+ WeChatConstants.secret);
System.out.println(result);
JSONObject json = JSONObject.parseObject(result);
return result;
}
/**
* @Description: 根据code获取access_token
* @Param: [code]
* @Author: xxs
* @Date: 2021/7/8 18:27
*/
public static WxGetAccessTokenByCode getAccessTokenByCode(String code){
String result= HttpUtil.get(WeChatConstants.getAccessTokenByCodeUrl+"appid=" + WeChatConstants.appId + "&secret="
+ WeChatConstants.secret + "&code=" + code + "&grant_type=authorization_code");
logger.info("获取access_token结果:"+result);
WxGetAccessTokenByCode wx = JSON.parseObject(result, WxGetAccessTokenByCode.class);
return wx;
}
/**
* @Description: 获取用户信息
* @Param: [access_token, openid]
* @Author: xxs
* @Date: 2021/7/8 17:19
*/
public static WxGetUserInfo getUserInfo(String access_token, String openid){
String result= HttpUtil.get(WeChatConstants.getUserInfoUrl+"access_token="+access_token+"&openid="+openid+"&lang=zh_CN");
logger.info("获取userInfo结果:"+result);
WxGetUserInfo userInfo = JSON.parseObject(result, WxGetUserInfo.class);
return userInfo;
}
}
package io.lease.modules.weixin.wxlogin;
import lombok.Data;
/**
* Created by xxs on 2021/11/30 10:22
*
* @Description
* {"access_token":"51_NsknBdrilaR5m5vXlxFZQ0Xda6iqKYiT2lLWHqzeHkaJ5Dm38pxuvMf_T9bK5p00rm29F3qYZvNAqV9bA87uYU2_Br7MfjxBTJ7cNRn98ZU",
* "expires_in":7200,
* "refresh_token":"51_11cz9rjjEtSCDpdW1-wNDDsjTkMlaFGLxeTJrbJnP6n5grzcz_IyctpHpwV0WJraVxXfiXf-xCPO4144UwEAi_g1hUAsXNLqLM4xE30x0-w",
* "openid":"oEMNh6tMYW39MQo4BNIgqhzHpYHs",
* "scope":"snsapi_userinfo"}
*/
@Data
public class WxGetAccessTokenByCode {
private String access_token;
private long expires_in;
private String refresh_token;
private String openid;
private String scope;
}
package io.lease.modules.weixin.wxlogin;
import lombok.Data;
import java.util.List;
/**
* Created by xxs on 2021/11/30 10:24
*
* @Description
* {"openid":"oEMNh6tMYW39MQo4BNIgqhzHpYHs",
* "nickname":"小小舍",
* "sex":0,
* "language":"",
* "city":"",
* "province":"",
* "country":"",
* "headimgurl":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJ9pZUKIXDQa4EGRzfGv0SooVKQoRy467Wr6C828UT3cwblic5yuVQqXUcQ08VFO8sJ580FPxz8PvQ\/132",
* "privilege":[]}
*/
@Data
public class WxGetUserInfo {
private String openid;
private String nickname;
private int sex;
private String language;
private String city;
private String province;
private String country;
private String headimgurl;
private List<String> privilege;
}
编写授权登录和授权回调接口
/**
* Created by xxs on 2021/7/8 17:55
* @Description: 公众号登录
* @Version: 2.9
*/
@RestController
@RequestMapping("/wxAuth")
public class GzhLoginController {
@Autowired
private GzhUserService gzhUserService;
private static Logger logger = LoggerFactory.getLogger(GzhLoginController.class);
/**
* @Author: xxs
* @Param: [response]
* @Date: 2021/7/9 8:56
* @Description: 授权登录方法
* @Version: 2.9
*/
@RequestMapping("/login")
public void wxLogin(HttpServletResponse response) throws IOException {
String redirect_uri =URLEncoder.encode(WeChatConstants.callBackUrl,"UTF-8");
//请求地址
String url = "https://open.weixin.qq.com/connect/oauth2/authorize" +
"?appid=" + WeChatConstants.appId + "&redirect_uri=" + redirect_uri +
"&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect";
System.out.println(url);
//重定向
response.sendRedirect(url);
}
/**
* @Author: xxs
* @Param: [request, response]
* @Date: 2021/7/9 8:56
* @Description: 授权登录回调方法
* @Version: 2.9
*/
@RequestMapping("/callBack")
public String wxCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
String code = request.getParameter("code");
logger.info("获取到code:"+code);
//获取access_token
WxGetAccessTokenByCode wx = WXAuthUtil.getAccessTokenByCode(code);
//请求获取userInfo
WxGetUserInfo userInfo = WXAuthUtil.getUserInfo(wx.getAccess_token(), wx.getOpenid());
//获取到userInfo,根据业务进行处理
GzhUser u = gzhUserService.insert(userInfo);
//重定向回公众号页面
String str = "openid="+u.getOpenid()+"&nickname="+u.getNickName()+"&headImgUrl="+u.getHeadImgUrl()+"&userId="+u.getUserId();
String param = (StrUtil.CheckNotNull(u.getPhone()))? str+"&phone="+u.getPhone():str;
// response.sendRedirect(WeChatConstants.redirectPageUrl+param);
return "success";
}
}
掉登录接口即可。