微信账号信任登录
概述
- 微信账号信任登录包含:PC网站应用登录、H5网站应用登录、小程序应用登录和APP移动应用登录
- 每种登录方式都需要配置不同的应用ID和应用秘钥
- 总体逻辑为:发起登录 -> 用户授权 -> 获取用户信息 -> 根据用户信息进行登录
PC网站应用登录
逻辑概述
- 第三方(Javashop网站)发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数
- 通过code参数加上AppID和AppSecret等,通过API换取access_token
- 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作
详细逻辑可参考官方文档:网站应用微信登录开发指南
流程图

重点步骤说明:
步骤3:构建的授权URL格式如下:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect网页授权作用域scope=snsapi_login,若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。
步骤10-11:
调用的接口为通过code获取access_token接口,如下:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code接口返回的数据格式如下:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}返回参数说明:
参数 描述 access_token 接口调用凭证 expires_in access_token接口调用凭证超时时间,单位(秒) refresh_token 用户刷新access_token openid 授权用户唯一标识 scope 用户授权的作用域,使用逗号(,)分隔 unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段 步骤12:根据unionid查询是否已经绑定注册了会员信息(查询es_connect表,此表存放的是第三方账号和系统会员的关联信息),如果未查询到数据,需要调用会员注册业务接口注册一条会员数据
步骤13:会员登录后会创建会员token信息,由于是服务端进行的重定向跳转页面,因此跳转之前要将token信息存入cookie中方便前端读取
代码展示
Controller代码展示:
@Tag(name = "微信统一登陆接口")
@RestController
@RequestMapping("/buyer/connect/wechat")
public class LoginByWechatController {
@Operation(summary = "PC端发起微信信任登录")
@GetMapping("/pc/login")
public void pcLogin() {
//信任登录插件基类
AbstractConnectLoginPlugin connectionLogin = connectManager.getConnectionLogin(ConnectTypeEnum.WECHAT);
String loginUrl = connectionLogin.getLoginUrl(ClientTypeEnum.PC.name());
try {
ThreadContextHolder.getHttpResponse().sendRedirect(loginUrl);
} catch (IOException e) {
this.logger.error(e.getMessage(), e);
throw new ServiceException(MemberErrorCode.E131.name(), "联合登录失败");
}
}
}
构建授权登录URL代码展示:
public class WechatSignaturer {
/**
* 获取微信授权url
*
* @param callbackUrl 回调地址
* @return
*/
public String getAuthorizeUrl(String callbackUrl) {
try {
HttpServletRequest request = ThreadContextHolder.getHttpRequest();
//获取买家 uuid
String uuid = request.getParameter("uuid");
String callBack = StringUtil.isEmpty(callbackUrl) ?
domainHelper.getCallback() + "/passport/connect/wechat/auth/back" : callbackUrl;
//获取微信信任登录PC端参数配置
Map map = this.thirdPlatformAppManager.getConfigOnConnect(ThirdPlatformEnum.WECHAT,ClientTypeEnum.PC);
String url = "https://open.weixin.qq.com/connect/qrconnect?" +
"appid=" + map.get("app_id").toString() +
"&redirect_uri=" + URLEncoder.encode(callBack, "GBK") +
"&response_type=code" +
"&scope=snsapi_login" +
"&state=" + uuid +
"#wechat_redirect";
return url;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
获取微信授权登录access_token代码展示:
public class WechatSignaturer {
/**
* 获取买家accesstoken
*
* @param client
* @return
*/
public Auth2Token getCallbackAccessToken(String client) {
HttpServletRequest request = ThreadContextHolder.getHttpRequest();
//获取code
String code = request.getParameter("code");
//回传uuid state
String uuid = request.getParameter("state");
//pc使用的是开放平台,微信端使用的是公众平台,参数是不一致
String ua = request.getHeader("user-agent").toLowerCase();
String appId = null;
String appSecret = null;
Map map;
ClientTypeEnum typeEnum = ClientTypeEnum.APP;
//如果是微信浏览器则获取 微信网页端参数
if (ua.indexOf("micromessenger") > 0) {
debugger.log("是微信浏览器");
typeEnum = ClientTypeEnum.H5;
} else if (client != null) {
typeEnum = ClientTypeEnum.valueOf(client.toUpperCase());
}
map = this.thirdPlatformAppManager.getConfigOnConnect(ThirdPlatformEnum.WECHAT, typeEnum);
appId = StringUtil.toString(map.get("app_id"));
appSecret = StringUtil.toString(map.get("app_secret"));
//文档见
//通过code获取access_token及openid
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + appId +
"&secret=" + appSecret +
"&code=" + code +
"&grant_type=authorization_code";
debugger.log("生成获取access_token url: ");
debugger.log(url);
debugger.log("向微信发起请求");
String content = HttpUtils.doGet(url, "UTF-8", 100, 1000);
debugger.log("微信返回内容为:");
debugger.log(content);
//获取openid
JSONObject json = JSONObject.fromObject(content);
String accessToken = json.getString("access_token");
String unionId = json.getString("unionid");
String refreshToken = json.getString("refresh_token");
Integer expires = json.getInt("expires_in");
//将信息封装到对象当中
Auth2Token auth2Token = new Auth2Token();
auth2Token.setUnionid(unionId);
if(!ClientTypeEnum.PC.equals(client)){
String openid = json.getString("openid");
auth2Token.setOpneId(openid);
}
auth2Token.setAccessToken(accessToken);
auth2Token.setRefreshToken(refreshToken);
auth2Token.setSessionSecret("111111111");
auth2Token.setType(ConnectTypeEnum.WECHAT.value());
auth2Token.setExpires(expires + DateUtil.getDateline());
auth2Token.setAppid(appId);
// 存储token 这里说明一下存储策略:
// 因为刷新token有效时间是1个月,但是买家不可能一个月不退出微信浏览器,所以这里为了缓存的占用问题,将token存储时间设置为24小时
this.cache.put(WechatSignaturer.BUYER_SIGNATURE + uuid, auth2Token, expires * 12);
debugger.log("生成accessToken:");
debugger.log(accessToken);
return auth2Token;
}
}
H5网站应用登录
逻辑概述
- 引导用户进入授权页面同意授权,获取code
- 通过code换取网页授权access_token(与基础支持中的access_token不同)
- 如果需要,开发者可以刷新网页授权access_token,避免过期
- 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
详细逻辑可参考官方文档:H5网页授权
流程图

重点步骤说明:
步骤2:调用微信H5获取授权页地址API时,需要上传前端指定的回调地址链接(需要使用 urlEncode 对链接进行处理)
步骤3:构建的授权URL格式如下:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect已认证服务号,默认拥有scope参数中的snsapi_base和snsapi_userinfo 权限,我们用到的是snsapi_userinfo
步骤10:跳转的页面地址就是第2步调用API时上传的回调地址,微信会自动携带上code和uuid(uuid就是state,是在第3步拼接授权页URL时设置的,如果不设置则不返回)
步骤12-13:
调用的接口为通过code换取网页授权access_token接口,如下:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code接口返回的数据格式如下:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"is_snapshotuser": 1,
"unionid": "UNIONID"
}返回参数说明:
参数 描述 access_token 接口调用凭证 expires_in access_token接口调用凭证超时时间,单位(秒) refresh_token 用户刷新access_token openid 授权用户唯一标识 scope 用户授权的作用域,使用逗号(,)分隔 is_snapshotuser 是否为快照页模式虚拟账号,只有当用户是快照页模式虚拟账号时返回,值为1 unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段 步骤14-15:
调用的接口为拉取用户信息接口,如下:
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN接口返回的数据格式如下:
{
"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"
}返回参数说明:
参数 描述 openid 用户的唯一标识 nickname 用户昵称 sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 province 用户个人资料填写的省份 city 普通用户个人资料填写的城市 country 国家,如中国为CN headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) unionid 只有在用户将公众号绑定到微信开放平台账号后,才会出现该字段。
代码展示
Controller代码展示:
@Tag(name = "微信统一登陆接口")
@RestController
@RequestMapping("/buyer/connect/wechat")
public class LoginByWechatController {
@Operation(summary = "微信H5获取授权页地址")
@Parameter(name = "redirectUri", description = "授权成功跳转地址(需要urlEncode整体加密)", required = true, in = ParameterIn.QUERY)
@GetMapping("/h5/getLoginUrl")
public String getLoginUrl(@RequestParam("redirectUri") String redirectUri){
return loginWeChatManager.getLoginUrl(redirectUri);
}
@Operation(summary = "微信H5登陆")
@Parameters({
@Parameter(name = "code", description = "code", in=ParameterIn.QUERY),
@Parameter(name = "uuid", description = "uuid", in=ParameterIn.QUERY),
})
@GetMapping("/h5/login")
public Map h5Login(String code, String uuid){
return loginWeChatManager.wxWapLogin(code,uuid);
}
}
业务接口代码展示:
@Service
public class LoginWeChatManagerImpl implements LoginWeChatManager {
/**
* 获取微信授权登录的url
*
* @param redirectUri 回调页面地址链接
* @return
*/
@Override
public String getLoginUrl(String redirectUri) {
Map<String, String> connectConfig = thirdPlatformAppManager.getConfigOnConnect(ThirdPlatformEnum.WECHAT,ClientTypeEnum.H5);
String appId = connectConfig.get("app_id");
StringBuffer loginBuffer = new StringBuffer("https://open.weixin.qq.com/connect/oauth2/authorize?");
loginBuffer.append("appid=").append(appId);
loginBuffer.append("&redirect_uri=").append(redirectUri);
loginBuffer.append("&response_type=code&scope=snsapi_userinfo&state=weixin#wechat_redirect");
return loginBuffer.toString();
}
/**
* 微信H5登陆
*
* @param code 微信h5授权返回的code
* @param uuid 本次请求的唯一标识
* @return
*/
@Override
public Map wxWapLogin(String code,String uuid) {
JSONObject accessTokenJson = this.getAccessToken(code, ClientTypeEnum.H5);
logger.debug("accessTokenJson==="+accessTokenJson.toString());
LoginUserDTO loginUserDTO = getLoginUserDTO(uuid, accessTokenJson);
return loginManager.loginByUnionId(loginUserDTO);
}
/**
* 获取accesstoken
*
* @param code 微信授权返回的code
* @param clientTypeEnum 客户端类型
* @return
*/
@Override
public JSONObject getAccessToken(String code, ClientTypeEnum clientTypeEnum) {
Map<String, String> connectConfig = thirdPlatformAppManager.getConfigOnConnect(ThirdPlatformEnum.WECHAT, clientTypeEnum);
String appId = connectConfig.get("app_id");
String secret = connectConfig.get("app_secret");
StringBuffer accessTokenBuffer = new StringBuffer("https://api.weixin.qq.com/sns/oauth2/access_token?");
accessTokenBuffer.append("appid=").append(appId);
accessTokenBuffer.append("&secret=").append(secret);
accessTokenBuffer.append("&code=").append(code);
accessTokenBuffer.append("&grant_type=authorization_code");
String access_token_back = HttpUtils.doGet(accessTokenBuffer.toString(),"UTF-8", 1000, 1000);
JSONObject jsonObject = JSONObject.fromObject(access_token_back);
logger.debug("getAccessToken==jsonObject==="+jsonObject.toString());
return jsonObject;
}
/**
* 获取登录用户信息
*
* @param uuid 登录请求唯一标识
* @param accessTokenJson 微信接口调用凭证相关信息
* @return
*/
private LoginUserDTO getLoginUserDTO(String uuid, JSONObject accessTokenJson) {
String accessToken = accessTokenJson.getString("access_token");
String openid = accessTokenJson.getString("openid");
LoginUserDTO loginUserDTO = new LoginUserDTO();
loginUserDTO.setUuid(uuid);
loginUserDTO.setTokenOutTime(null);
loginUserDTO.setRefreshTokenOutTime(null);
loginUserDTO.setOpenid(openid);
loginUserDTO.setOpenType(ConnectTypeEnum.WECHAT_OPENID);
loginUserDTO = this.getWechatInfo(loginUserDTO, accessToken, openid);
loginUserDTO.setUnionType(ConnectTypeEnum.WECHAT);
if (StringUtil.isEmpty(loginUserDTO.getUnionid())) {
throw new ServiceException("403", "请将公众号绑定到微信开放平台");
}
return loginUserDTO;
}
/**
* 获取微信用户信息
*
* @param loginUserDTO 登录用户信息
* @param accessToken 接口调用凭证
* @param openId 用户微信openid
* @return
*/
private LoginUserDTO getWechatInfo(LoginUserDTO loginUserDTO,String accessToken, String openId) {
StringBuffer wechatInfoBuffer = new StringBuffer("https://api.weixin.qq.com/sns/userinfo?");
wechatInfoBuffer.append("access_token=").append(accessToken);
wechatInfoBuffer.append("&openid=").append(openId);
wechatInfoBuffer.append("&lang=zh_CN");
String user_info_back = HttpUtils.doGet(wechatInfoBuffer.toString(),"UTF-8", 1000, 1000);
JSONObject wechatInfoJson = JSONObject.fromObject(user_info_back);
logger.debug("getWechatInfo==wechatInfoJson==="+wechatInfoJson.toString());
loginUserDTO.setHeadimgurl(wechatInfoJson.getString("headimgurl"));
loginUserDTO.setNickName(wechatInfoJson.getString("nickname"));
if (wechatInfoJson.get("unionid")!=null){
loginUserDTO.setUnionid(wechatInfoJson.getString("unionid"));
}
loginUserDTO.setSex(wechatInfoJson.getInt("sex")==1?1:0);
return loginUserDTO;
}
}
小程序登录
逻辑概述
- 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器(Javashop服务器)
- 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账号) 和 会话密钥 session_key
具体逻辑可参考官方文档:小程序登录
流程图

当前流程图转自官方文档
注意事项:
- 会话密钥
session_key是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。 - 临时登录凭证 code 只能使用一次
代码展示
Controller代码展示:
@Tag(name = "微信统一登陆接口")
@RestController
@RequestMapping("/buyer/connect/wechat")
public class LoginByWechatController {
@Operation(summary = "小程序登陆")
@PostMapping("/mini/login")
public Map miniLogin(WeChatMiniLoginDTO weChatMiniLoginDTO){
return loginWeChatManager.miniLogin(weChatMiniLoginDTO);
}
}
业务接口代码展示:
@Service
public class LoginWeChatManagerImpl implements LoginWeChatManager {
/**
* 小程序登陆
*
* @param weChatMiniLoginDTO 小程序登录参数
* @return
*/
@Override
public Map miniLogin(WeChatMiniLoginDTO weChatMiniLoginDTO) {
Map res = new HashMap(16);
LoginUserDTO loginUserDTO = new LoginUserDTO();
loginUserDTO.setUuid(weChatMiniLoginDTO.getUuid());
loginUserDTO.setTokenOutTime(WX_TOKEN_VAILD_TIME_MINI);
loginUserDTO.setRefreshTokenOutTime(WX_TOKEN_VAILD_TIME_MINI);
String content = wxMiniAutoCode(weChatMiniLoginDTO.getCode());
if (StringUtil.isEmpty(content)){
res.put("autologin", "fail");
res.put("reason", "auth_code_fail");
return res;
}
JSONObject json = JSONObject.fromObject(content);
String unionId = json.getString("unionid");
if (StringUtil.isEmpty(unionId)){
res.put("autologin", "fail");
res.put("reason", "fail_to_get_unionid");
return res;
}
String openid = json.getString("openid");
loginUserDTO.setOpenid(openid);
loginUserDTO.setOpenType(ConnectTypeEnum.WECHAT_MINI);
// 获取会话密钥(session_key)
String sessionKey = json.get("session_key").toString();
cache.put(WX_MINI_SESSIONKEY+openid,sessionKey,60*60*24*2);
//获取不到unionid
JSONObject userInfoJson = connectManager.getUserInfo(weChatMiniLoginDTO.getEdata(), sessionKey, weChatMiniLoginDTO.getIv());
logger.debug("miniLogin==userInfoJson==="+userInfoJson.toString());
loginUserDTO.setUnionid(unionId);
loginUserDTO.setUnionType(ConnectTypeEnum.WECHAT);
loginUserDTO.setHeadimgurl(userInfoJson.get("avatarUrl")==null?null:userInfoJson.getString("avatarUrl"));
loginUserDTO.setNickName(userInfoJson.get("nickName")==null?null:userInfoJson.getString("nickName"));
loginUserDTO.setSex(userInfoJson.getInt("gender")==1?1:0);
return loginManager.loginByUnionId(loginUserDTO);
}
}
APP移动应用登录
逻辑概述
- 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数
- 通过code参数加上AppID和AppSecret等,通过API换取access_token
- 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作
具体逻辑可参考官方文档:移动应用微信登录开发指南
流程图

重点步骤说明:
步骤2-3:用户点击授权登录后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK 通过 SendAuth 的 Resp 返回数据给调用方
步骤7-8:
调用的接口为通过code获取access_token接口,如下:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code接口返回的数据格式如下:
{
"access_token": "ACCESS_TOKEN",
"expires_in": 7200,
"refresh_token": "REFRESH_TOKEN",
"openid": "OPENID",
"scope": "snsapi_userinfo",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}返回参数说明:
参数 描述 access_token 接口调用凭证 expires_in access_token接口调用凭证超时时间,单位(秒) refresh_token 用户刷新access_token openid 授权用户唯一标识 scope 用户授权的作用域,使用逗号(,)分隔 unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段 步骤9-10:
调用的接口为拉取用户信息接口,如下:
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN接口返回的数据格式如下:
{
"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"
}返回参数说明:
参数 描述 openid 用户的唯一标识 nickname 用户昵称 sex 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 province 用户个人资料填写的省份 city 普通用户个人资料填写的城市 country 国家,如中国为CN headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 privilege 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) unionid 只有在用户将公众号绑定到微信开放平台账号后,才会出现该字段。
代码展示
Controller代码展示:
@Tag(name = "微信统一登陆接口")
@RestController
@RequestMapping("/buyer/connect/wechat")
public class LoginByWechatController {
@Operation(summary = "APP登陆")
@GetMapping("/app/login")
public Map appLogin(String code, String uuid){
return loginWeChatManager.wxAppLogin(code,uuid);
}
}
业务接口代码展示:
@Service
public class LoginWeChatManagerImpl implements LoginWeChatManager {
/**
* APP微信登陆
*
* @param code 微信h5授权返回的code
* @param uuid 本次请求的唯一标识
* @return
*/
@Override
public Map wxAppLogin(String code, String uuid) {
JSONObject accessTokenJson = this.getAccessToken(code, ClientTypeEnum.APP);
logger.debug("accessTokenJson==="+accessTokenJson.toString());
LoginUserDTO loginUserDTO = getLoginUserDTO(uuid, accessTokenJson);
return loginManager.loginByUnionId(loginUserDTO);
}
/**
* 获取accesstoken
*
* @param code 微信授权返回的code
* @param clientTypeEnum 客户端类型
* @return
*/
@Override
public JSONObject getAccessToken(String code, ClientTypeEnum clientTypeEnum) {
Map<String, String> connectConfig = thirdPlatformAppManager.getConfigOnConnect(ThirdPlatformEnum.WECHAT, clientTypeEnum);
String appId = connectConfig.get("app_id");
String secret = connectConfig.get("app_secret");
StringBuffer accessTokenBuffer = new StringBuffer("https://api.weixin.qq.com/sns/oauth2/access_token?");
accessTokenBuffer.append("appid=").append(appId);
accessTokenBuffer.append("&secret=").append(secret);
accessTokenBuffer.append("&code=").append(code);
accessTokenBuffer.append("&grant_type=authorization_code");
String access_token_back = HttpUtils.doGet(accessTokenBuffer.toString(),"UTF-8", 1000, 1000);
JSONObject jsonObject = JSONObject.fromObject(access_token_back);
logger.debug("getAccessToken==jsonObject==="+jsonObject.toString());
return jsonObject;
}
/**
* 获取登录用户信息
*
* @param uuid 登录请求唯一标识
* @param accessTokenJson 微信接口调用凭证相关信息
* @return
*/
private LoginUserDTO getLoginUserDTO(String uuid, JSONObject accessTokenJson) {
String accessToken = accessTokenJson.getString("access_token");
String openid = accessTokenJson.getString("openid");
LoginUserDTO loginUserDTO = new LoginUserDTO();
loginUserDTO.setUuid(uuid);
loginUserDTO.setTokenOutTime(null);
loginUserDTO.setRefreshTokenOutTime(null);
loginUserDTO.setOpenid(openid);
loginUserDTO.setOpenType(ConnectTypeEnum.WECHAT_OPENID);
loginUserDTO = this.getWechatInfo(loginUserDTO, accessToken, openid);
loginUserDTO.setUnionType(ConnectTypeEnum.WECHAT);
if (StringUtil.isEmpty(loginUserDTO.getUnionid())) {
throw new ServiceException("403", "请将公众号绑定到微信开放平台");
}
return loginUserDTO;
}
/**
* 获取微信用户信息
*
* @param loginUserDTO 登录用户信息
* @param accessToken 接口调用凭证
* @param openId 用户微信openid
* @return
*/
private LoginUserDTO getWechatInfo(LoginUserDTO loginUserDTO,String accessToken, String openId) {
StringBuffer wechatInfoBuffer = new StringBuffer("https://api.weixin.qq.com/sns/userinfo?");
wechatInfoBuffer.append("access_token=").append(accessToken);
wechatInfoBuffer.append("&openid=").append(openId);
wechatInfoBuffer.append("&lang=zh_CN");
String user_info_back = HttpUtils.doGet(wechatInfoBuffer.toString(),"UTF-8", 1000, 1000);
JSONObject wechatInfoJson = JSONObject.fromObject(user_info_back);
logger.debug("getWechatInfo==wechatInfoJson==="+wechatInfoJson.toString());
loginUserDTO.setHeadimgurl(wechatInfoJson.getString("headimgurl"));
loginUserDTO.setNickName(wechatInfoJson.getString("nickname"));
if (wechatInfoJson.get("unionid")!=null){
loginUserDTO.setUnionid(wechatInfoJson.getString("unionid"));
}
loginUserDTO.setSex(wechatInfoJson.getInt("sex")==1?1:0);
return loginUserDTO;
}
}