首先是微信公众号的官方开发文档
首先需要一张能接收微信字段的表和一张自己用户的信息表
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("XXX")
@ApiModel(value="XXX对象", description="微信用户")
public class OmsWeixinUserInfo {
@TableId(value = "openid")
private String openid;
@ApiModelProperty(value = "unionid")
private String unionid;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "用户的性别(1是男性,2是女性,0是未知)")
private Short sex;
@ApiModelProperty(value = "用户所在国家")
private String country;
@ApiModelProperty(value = "用户所在省份")
private String province;
@ApiModelProperty(value = "用户所在城市")
private String city;
@ApiModelProperty(value = "用户头像")
private String headimgurl;
@ApiModelProperty(value = "状态 -1.删除, 1.启用, 2.停用")
private Short status;
@ApiModelProperty(value = "创建人")
private String createUser;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改人")
private String updateUser;
@ApiModelProperty(value = "修改时间")
private Date updateTime;
}
自己的用户表
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("XXX")
@ApiModel(value="XXX对象", description="用户表")
public class OmsUser {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "手机号")
private String phone;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "生日")
private Date birthday;
@ApiModelProperty(value = "证件类型 1.身份证,2.护照,3.港澳通行证")
private Short idType;
@ApiModelProperty(value = "证件号码")
private String idNumber;
@ApiModelProperty(value = "所属上级")
private Integer pid;
@ApiModelProperty(value = "unionid")
private String unionid;
@ApiModelProperty(value = "用户的标识")
private String openid;
@ApiModelProperty(value = "昵称")
private String nickname;
@ApiModelProperty(value = "用户的性别(1是男性,2是女性,0是未知)")
private Short sex;
@ApiModelProperty(value = "用户所在国家")
private String country;
@ApiModelProperty(value = "用户所在省份")
private String province;
@ApiModelProperty(value = "用户所在城市")
private String city;
@ApiModelProperty(value = "用户头像")
private String headimgurl;
@ApiModelProperty(value = "状态 -1.删除, 1.启用, 2.停用")
private Short status;
@ApiModelProperty(value = "创建人")
private String createUser;
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改人")
private String updateUser;
@ApiModelProperty(value = "修改时间")
private Date updateTime;
}
工具类 把返回的结果转成为JSON对象
public class OmsJSONUtil {
public static JSONObject doGetJson(String url) throws Exception {
JSONObject jsonObject = null;
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet =new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity =response.getEntity();
if(entity != null)
{
//把返回的结果转换为JSON对象
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSON.parseObject(result);
}
return jsonObject;
}
}
首先就是Controller层 本身是暴露接口不做处理
@RestController
@RequestMapping("/XXX")
@Api(tags = {"XXX"})
@Slf4j
public class OmsMPController {
@ApiOperation("公众号微信登录授权同意之后回调地址")
@ApiOperationSupport(order = 3)
@GetMapping("/callBack")
public ResponseUtil<Map<String, Object>> callBack(@Valid @ApiParam("code") String code,
@ApiParam("非必填") @Nullable Integer pid) throws Exception {
if (StringUtils.isBlank(code)) {
return ResponseUtil.fail("缺少主要参数 code");
}
return omsWeixinUserInfoService.callBack(code, pid);
}
}
Service接口层
public interface IOmsWeixinUserInfoSerivce extends IService<OmsWeixinUserInfo> {
ResponseUtil<Map<String, Object>> callBack(String code, Integer pid) throws Exception;
}
实现类
通过code换取网页授权access_token
首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
尤其注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。
请求方法
获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
返回说明
正确时返回的JSON数据包如下:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"is_snapshotuser": 1,
"unionid": "UNIONID"
}
拉取用户信息(需scope为 snsapi_userinfo)
如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
请求方法
http:GET(请使用https协议):
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
返回说明
正确时返回的JSON数据包如下:
{
"openid": "OPENID",
"nickname": NICKNAME,
"sex": 1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
开上代码 app_id 和 app_secret 根据你自己的填写就行
@Service
@Slf4j
public class OmsWeixinUserInfoSerivceImpl extends ServiceImpl<OmsWeixinUserInfoMapper , OmsWeixinUserInfo> implements IOmsWeixinUserInfoSerivce {
/* 公众账号appid,首先申请与之配套的公众账号 */
private static final String app_id = "";
/* 公众号secret,用户获取用户授权token */
private static final String app_secret = "";
/* 用户Service */
@Resource
private IOmsUserService omsUserService;
/* 微信用户Service */
@Resource
private IOmsWeixinUserInfoSerivce omsWeixinUserInfoService;
@Resource
private HttpServletRequest request;
@Transactional(rollbackFor = Exception.class)
@Override
public ResponseUtil<Map<String, Object>> callBack(String code, Integer pid) throws Exception {
OmsUser omsUser = new OmsUser();
OmsWeixinUserInfo weixinUserInfo = new OmsWeixinUserInfo();
//通过code换取网页授权access_token
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + app_id
+ "&secret=" + app_secret
+ "&code=" + code
+ "&grant_type=authorization_code";
JSONObject jsonObject = OmsJSONUtil.doGetJson(url);
String openid = jsonObject.getString("openid");
if (StringUtils.isBlank(openid)) {
log.error("openid为null");
return ResponseUtil.fail("openid是空" + Constants.NOT_FOUND_DATA);
}
String access_token = jsonObject.getString("access_token");
String refresh_token = jsonObject.getString("refresh_token");
// 拉取用户信息(需scope为 snsapi_userinfo)
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token
+ "&openid=" + openid
+ "&lang=zh_CN";
JSONObject userInfo = OmsJSONUtil.doGetJson(infoUrl);
if (userInfo == null) {
return ResponseUtil.fail("---结束---" + Constants.NOT_FOUND_DATA);
}
//根据openid去库里查有没有
OmsWeixinUserInfo weixinUserInfoOpenid = omsWeixinUserInfoService.listOpenid(openid);
if (Objects.nonNull(weixinUserInfoOpenid)) {
OmsUser omsUserById = omsUserService.listById(openid);
//如果omsUserById 不等于null 就修改 等于null 说明库里没有就添加
if (Objects.nonNull(omsUserById)) {
Integer id = omsUserById.getId();
//如果你当前下线的 id 于 传进来的 pid 相等 则你不可以成为他的下线
LambdaQueryWrapper<OmsUser> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(OmsUser::getPid, id)
.ne(OmsUser::getStatus, CommonOtaStatusEnum.DELETE.getValue())
.select(OmsUser::getId);
Set<OmsUser> omsUserSet = omsUserService.list(wrapper).stream().filter(oms -> oms.getId().equals(pid)).collect(Collectors.toSet());
if (omsUserSet.isEmpty()) {
//如果pid == 0 或者 null 说明没有上级 可以把pid加进去成为他的下级
if (omsUserById.getPid().equals(OmsStatusEnum.OTHER.getNumber()) || omsUserById.getPid() == null) {
omsUser.setId(id);
omsUser.setPid(pid);
omsUser.setUpdateUser(omsUserById.getName());
omsUser.setUpdateTime(new Date());
omsUserService.saveOrUpdate(omsUser);
}
//把token和openid返给前端
Map<String, Object> map = new HashMap<>();
String token = TokenUtil.cacheToken(id, LoginEnum.PUBLIC_ACCOUNT_KEY.getValue());
map.put("token", token);
map.put("openid", openid);
return ResponseUtil.success(map);
}
//把token和openid返给前端
Map<String, Object> map = new HashMap<>();
String token = TokenUtil.cacheToken(id, LoginEnum.PUBLIC_ACCOUNT_KEY.getValue());
map.put("token", token);
map.put("openid", openid);
map.put("error", "对方是你的下级,你无法成为对方的下级");
return ResponseUtil.success(map);
}
//存进用户表
BeanUtils.copyProperties(weixinUserInfoOpenid, omsUser);
omsUser.setName(userInfo.getString("nickname"));
omsUser.setPhone(OmsStatusEnum.OTHER.getValue());
omsUser.setEmail(OmsStatusEnum.OTHER.getValue());
omsUser.setIdType((short) 1);
omsUser.setIdNumber(OmsStatusEnum.OTHER.getValue());
omsUser.setCreateUser(userInfo.getString("nickname"));
omsUser.setCreateTime(new Date());
omsUser.setStatus(CommonOtaStatusEnum.OPEN.getValue());
omsUser.setPid(pid != null ? pid : Constants.ZERO);
omsUserService.save(omsUser);
//把token和openid返给前端
Map<String, Object> map = new HashMap<>();
String token = TokenUtil.cacheToken(omsUser.getId(),
LoginEnum.PUBLIC_ACCOUNT_KEY.getValue());
map.put("token", token);
map.put("openid", openid);
return ResponseUtil.success(map);
}
//存进微信用户表
//unionid
weixinUserInfo.setUnionid(userInfo.getString("unionid"));
// 用户的标识
weixinUserInfo.setOpenid(openid);
// 昵称
weixinUserInfo.setNickname(userInfo.getString("nickname"));
// 用户的性别(1是男性,2是女性,0是未知)
weixinUserInfo.setSex(userInfo.getShort("sex"));
// 用户所在国家
weixinUserInfo.setCountry(userInfo.getString("country"));
// 用户所在省份
weixinUserInfo.setProvince(userInfo.getString("province"));
// 用户所在城市
weixinUserInfo.setCity(userInfo.getString("city"));
// 用户头像
weixinUserInfo.setHeadimgurl(userInfo.getString("headimgurl"));
weixinUserInfo.setCreateUser(userInfo.getString("nickname"));
weixinUserInfo.setCreateTime(new Date());
weixinUserInfo.setStatus(CommonOtaStatusEnum.OPEN.getValue());
omsWeixinUserInfoService.save(weixinUserInfo);
//存进用户表
BeanUtils.copyProperties(weixinUserInfo, omsUser);
omsUser.setName(userInfo.getString("nickname"));
omsUser.setPhone(OmsStatusEnum.OTHER.getValue());
omsUser.setEmail(OmsStatusEnum.OTHER.getValue());
omsUser.setIdType((short) 1);
omsUser.setIdNumber(OmsStatusEnum.OTHER.getValue());
omsUser.setCreateUser(userInfo.getString("nickname"));
omsUser.setCreateTime(new Date());
omsUser.setStatus(CommonOtaStatusEnum.OPEN.getValue());
omsUser.setPid(pid != null ? pid : Constants.ZERO);
omsUserService.save(omsUser);
//把token和openid返给前端
Map<String, Object> map = new HashMap<>();
String token = TokenUtil.cacheToken(omsUser.getId(),
LoginEnum.PUBLIC_ACCOUNT_KEY.getValue());
map.put("token", token);
map.put("openid", openid);
return ResponseUtil.success(map);
}
我们来测试一下
成功了 返回了一条Token给前端
看一下数据库微信表
用户表