Java 微信登陆
code、encryptedData、iv:
需要前端通过wx.login获取code,wx.getUserInfo获取encryptedData用户数据加密、iv偏移向量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public UserDto login(String code, String encryptedData, String iv) throws Exception {
WxSessionModel wxSession = wxClientApi.getSessionKey(WxSessionModel.class, code); WxUserModel wxUser = wxClientApi.getUserInfo(WxUserModel.class, wxSession.getSession_key(), encryptedData, iv); UserDto user = proxy.queryUserByUid(wxUser.getOpenId()); if (user == null) { user = registUser(wxUser); } else { user.setName(wxUser.getNickName()); user.setAvatarUrl(wxUser.getAvatarUrl()); user.setSex(wxUser.getGender()); reactor.notify("updateUserHandler", Event.wrap(user)); } proxy.saveUserByUid(user); log.info("用户登录:" + user); return user; }
|
getSessionKey(Class resultClass, String code)
请求地址:api.weixin.qq.com/sns/jscode2session
根据前端传的code请求微信接口获取session
checkCode(HttpResponse response),对请求微信接口的结果做异常处理,有errcode!=0和,httpcode!=200的时候抛异常
1 2 3 4 5 6 7 8 9 10 11 12
| public <T> T getSessionKey(Class<T> resultClass, String code) throws Exception {
HttpRequest request = new HttpRequest(makeHttpsUrl("sessionPath")); request.addParameter("appid", getProperties("AppID")); request.addParameter("secret", getProperties("AppSecret")); request.addParameter("js_code", code); request.addParameter("grant_type", "authorization_code"); HttpResponse response = clientManager.execute(request); checkCode(response); return JsonUtility.toObject(response.getContentString(), resultClass); }
|
最终json反序列化,返回这样的类
1 2 3 4 5 6 7 8
| public class WxSessionModel {
private Integer errcode; private String errmsg; private String openid; private String session_key; private String unionid; }
|
application-local.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| http: enabled: true time-out-socket: 5000 time-out-connection: 2000 time-out-request-connection: 5000 retry-number: 2 max-total: 500 client-properties: weixin: host: api.weixin.qq.com max-pre-route: 100 url-map: sessionPath: /sns/jscode2session TokenPath: /cgi-bin/token ScoreStoragePath: /wxa/set_user_storage AppID: xxxxxxxxxxx AppSecret: xxxxxx
|
getUserInfo(Class resultClass, String sessionKey, String encryptedData, String iv)
解密前端传入的encryptedData加密用户信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| public <T> T getUserInfo(Class<T> resultClass, String sessionKey, String encryptedData, String iv) { byte[] dataByte = Base64.decode(encryptedData); byte[] keyByte = Base64.decode(sessionKey); byte[] ivByte = Base64.decode(iv);
try { 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 JsonUtility.toObject(result, resultClass); } } catch (Exception e) { e.printStackTrace(); } return null; }
|
解密后,返回这样的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class WxUserModel { private String nickName; private String openId; private String unionId; private String avatarUrl; private Integer gender = Constant.Gender.Nomal.ordinal(); }
public enum Gender { Nomal, Man, Woman }
|
总结
主要是没有做过获取微信用户信息这一块,后面的操作就是业务逻辑,存在我们自己的数据库了,唯一标识就是wx的openId