目录
准备工作
在微信开放平台申请微信登录
微信开放平台:https://open.weixin.qq.com/
微信登录开发文档:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html
创建相应应用,审核通过后查看APPID和SECRET
业务流程
APP和网站接入微信登录仅获取code不同,详情见文档https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Authorized_Interface_Calling_UnionID.html
1、前端向微信获取code
2、带code请求后台接口,由后台接口请求微信access_token
3、在后台接口获取到access_token后,带access_token请求微信的获取用户个人信息(UnionID机制)接口获取该微信用户的信息。如果后期有调用微信其它接口需要用到access_token的需求,可以在这步对access_token进行保存及有效时长刷新操作(具体接口见文档)。
注意:
SECRET 和access_token不可存在前端,存在安全隐患。
后台接口实现
@RestController
@RequestMapping("/api/weChatLogin")
public class WeChatLoginController extends BaseController {
@Resource
private EhCacheUtil ehcacheUtil;
/**
* 通过 code 获取 access_token
*/
private final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
/**
* 获取用户个人信息(UnionID 机制)
*/
private final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";
private final String APP_ID = "";
private final String SECRET = "";
/**
* 微信登陆
* @param code 从微信获取的code
* @param lat 登陆维度
* @param lng 登陆经度
*/
@RequestMapping("/login")
public Map weChatLogin(String code, String lat, String lng, HttpServletRequest request) throws HttpProcessException {
if (isNull(code)) {
return fail("缺少code");
}
HttpConfig httpConfig = HttpConfig.custom().url(ACCESS_TOKEN_URL).encoding("utf-8");
String getTokenResultStr = HttpClientUtil.get(httpConfig);//向微信请求
System.out.println("通过CODE:" + code + "获取access_token结果:" + getTokenResultStr);
JSONObject getTokenResult = JSONObject.parseObject(getTokenResultStr);
//判断是否成功获取access_token
if (getTokenResult.containsKey("errcode")) {
return fail(getTokenResult.getString("errmsg"));
}
String access_token = getTokenResult.getString("access_token");
String openid = getTokenResult.getString("openid");
//通过openid查询是否已经在库里
QueryWrapper<MobileUser> mobileUserQueryWrapper = new QueryWrapper<>();
mobileUserQueryWrapper.eq("openId", openid);
MobileUser mobileUser = mobileUserService.getOne(mobileUserQueryWrapper);
if (mobileUser != null) {
if (!isNull(lat) && !isNull(lng)) {
mobileUser.setLoginLat(lat);
mobileUser.setLoginLng(lng);
mobileUserService.updateById(mobileUser);//更新登陆经纬度
}
//该微信用户已绑定账号 直接返回用户信息
HttpSession session = request.getSession();
session.setAttribute("user", net.sf.json.JSONObject.fromObject(mobileUser));
ehcacheUtil.put(session.getId(),"true");
Map<String, Object> data = new HashMap<>();
data.put("id", mobileUser.getId());
data.put("name", mobileUser.getName());
data.put("sex", mobileUser.getSex());
data.put("headPath", mobileUser.getHeadPath());
data.put("integral", mobileUser.getIntegral());
data.put("invitationCode", mobileUser.getInvitationCode());
data.put("familyId", mobileUser.getFamilyId());
data.put("status", mobileUser.getStatus());
data.put("isCheckedT", mobileUser.getIsCheckedT());
Vip vip = vipService.getById(mobileUser.getVipId());
if (vip == null) {
data.put("vip", "");
} else {
data.put("vip", vip.getName());
}
return success(data);
}
//微信用户登陆没有绑定账号 获取微信用户信息
HttpConfig userHttpConfig = HttpConfig.custom().url(USER_INFO_URL).encoding("utf-8");
String getUserResultStr = HttpClientUtil.get(userHttpConfig);
JSONObject getUserResult = JSONObject.parseObject(getUserResultStr);
System.out.println("通过OPENID:" + openid + "获取用户信息:" + getUserResultStr);
//判断获取微信用户信息是否成功
if (getUserResult.containsKey("errcode")) {
return fail(getUserResult.getString("errmsg"));
}
mobileUser = new MobileUser();
mobileUser.setName(getUserResult.getString("nickname"));
String sex = getUserResult.getString("sex");
if (sex != null) {
if (sex.equals("1")) {
mobileUser.setSex("男");
} else {
mobileUser.setSex("女");
}
}
mobileUser.setProvince(getUserResult.getString("province"));
mobileUser.setCity(getUserResult.getString("city"));
mobileUser.setCounty(getUserResult.getString("country"));
mobileUser.setHeadPath(getUserResult.getString("headimgurl"));
mobileUser.setOpenId(getUserResult.getString("openid"));
mobileUser.setUnionId(getUserResult.getString("unionid"));
//将微信用户信息写入用户表
if (mobileUserService.save(mobileUser)) {
return successMsg(404, "请进行账号绑定或注册", openid);
}
return fail("登陆失败");
}
}
<!--httpclient工具类https://github.com/Arronlong/httpclientutil-->
<dependency>
<groupId>com.arronlong</groupId>
<artifactId>httpclientutil</artifactId>
<version>1.0.4</version>
</dependency>