登录接口
官网地址:https://developers.weixin.qq.com/miniprogram/dev/api/code2Session.html
参考地址:https://blog.csdn.net/abcwanglinyong/article/details/80267901
@ApiOperation(notes = "/login", httpMethod = "POST", value = "登录")
@ResponseBody
@RequestMapping(value = "/login", method = RequestMethod.POST)
public LoginRegisterResult doLogin(@RequestBody LoginParams params){
LOGGER.info( "小程序登录==" );
LoginRegisterResult registerResult = new LoginRegisterResult();
if (StringUtils.isNotBlank(params.getCode())) {
//调取微信中 用户openID
JSONObject sessionKeyOpenId = getSessionKeyOrOpenId(params.getCode());
String openid = sessionKeyOpenId.getString("openid" );
String sessionKey = sessionKeyOpenId.getString( "session_key" );
// String unionid = sessionKeyOpenId.getString( "unionid" );
LOGGER.info("openid {},session_key{}",openid,sessionKey);
JSONObject userInfo = getUserInfo( params.getEncrypteData(), sessionKey, params.getIv() );
LOGGER.info("根据解密算法获取的userInfo="+userInfo);
ApplentUserInfoDto dto = FastJsonUtil.parseToObject(userInfo.toJSONString(), ApplentUserInfoDto.class);
//用户信息保存到库中
Channel channel = getChannelByCode(getChannelCodeByTouristUUid());
ReaderUserLoginAccount readerUserLoginAccount = addReader(dto, channel);
//将用户信息放到redis
//根据unionid生成token
String encrypt = SimpleAesUtil.encrypt(readerUserLoginAccount.getAccount_num());
readerCloudManager.setReaderUser(encrypt, readerUserLoginAccount.getReader_id());
LOGGER.info("微信登录成功,token:{},user Id:{}", encrypt, readerUserLoginAccount.getReader_id());
//返给前端信息
registerResult.setCode(OperationStatus.SUCCESS.getType());
registerResult.setMsg(OperationStatus.SUCCESS.getName());
registerResult.setToken(encrypt);
registerResult.setApplent_open_id(openid);
return registerResult;
}
registerResult.setCode(OperationStatus.FAIL.getType());
registerResult.setMsg(OperationStatus.FAIL.getName());
return registerResult;
}
public JSONObject getSessionKeyOrOpenId(String code){
//微信端登录code
StringBuffer params = new StringBuffer();
params.append(conf.get(ApiConstant.WEIXIN_APPLENT_LOGIN_OPENID_URL));
params.append("?appid=").append(conf.get(ApiConstant.WEIXIN_APPLENT_APPID));
params.append("&secret=").append(conf.get(ApiConstant.WEIXIN_APPLENT_SECRET));
params.append("&js_code=").append(code);
params.append("&grant_type=authorization_code");
String result = HttpClientUtil.sendGet(params.toString());
LOGGER.info("小程序 获取OpenID 请求:{},结果:{}", params.toString(), result);
return JSON.parseObject(result);
}
//解密获取用户信息
public static JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){
// 被加密的数据
byte[] dataByte = Base64.decodeBase64(encryptedData);
byte[] keyByte = Base64.decodeBase64(sessionKey);
byte[] ivByte = Base64.decodeBase64(iv);
try {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
int base = 16;
if (keyByte.length % base != 0) {
int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
keyByte = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
cipher.init( Cipher.DECRYPT_MODE, spec, parameters);// 初始化
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
String result = new String(resultByte, "UTF-8");
return JSON.parseObject(result);
}
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e.getMessage(), e);
} catch (NoSuchPaddingException e) {
LOGGER.error(e.getMessage(), e);
} catch (InvalidParameterSpecException e) {
LOGGER.error(e.getMessage(), e);
} catch (IllegalBlockSizeException e) {
LOGGER.error(e.getMessage(), e);
} catch (BadPaddingException e) {
LOGGER.error(e.getMessage(), e);
} catch (UnsupportedEncodingException e) {
LOGGER.error(e.getMessage(), e);
} catch (InvalidKeyException e) {
LOGGER.error(e.getMessage(), e);
} catch (InvalidAlgorithmParameterException e) {
LOGGER.error(e.getMessage(), e);
} catch (NoSuchProviderException e) {
LOGGER.error(e.getMessage(), e);
}
return null;
}
//解密获取的实体类
/**
* 小程序登录 返回用户信息
*/
public class ApplentUserInfoDto{
/**
* 用户的唯一标识
*/
private String openId;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户的性别,性别 0:未知、1:男、2:女
*/
private int gender;
/**
* 用户所在省份
*/
private String province;
/**
* 用户所在城市
*/
private String city;
/**
* 用户所在国家
*/
private String country;
/**
* 用户唯一id
*/
private String unionId;
/**
* 用户头像图片的 URL
*/
private String avatarUrl;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
}