提交 469558bd 编写于 作者: H harrylee

集成京东

上级 d9952968
......@@ -690,7 +690,7 @@ public enum AuthDefaultSource implements AuthSource {
@Override
public String userInfo() {
return null;
return "https://api.jd.com/routerjson";
}
@Override
......
......@@ -7,15 +7,24 @@ import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthResponseStatus;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.TreeMap;
/**
* 京东登录
* link: http://open.jd.com/home/home#/doc/common?listId=717
*
* @author harry.lee (harryleexyz@qq.com)
* @since
......@@ -51,9 +60,86 @@ public class AuthJdRequest extends AuthDefaultRequest {
.build();
}
/**
* link: http://jos.jd.com/api/showTools.htm?id=3051&groupId=106
* postUrl: https://api.jd.com/routerjson?v=2.0&method=jingdong.user.getUserInfoByOpenId
* &app_key=x&access_token=x&360buy_param_json={"openId":"x"}
* &timestamp=2019-09-11 11:12:26&sign=DB5278CD12443BEA22C5E5EA05A30D2B
* @param authToken token信息
* @return
*/
@Override
protected AuthUser getUserInfo(AuthToken authToken) {
return null;
UrlBuilder urlBuilder = UrlBuilder.fromBaseUrl(source.userInfo())
.queryParam("access_token", authToken.getAccessToken())
.queryParam("app_key", config.getClientId())
.queryParam("method", "jingdong.user.getUserInfoByOpenId")
.queryParam("360buy_param_json", "{\"openId\":\"" + authToken.getOpenId() + "\"}")
.queryParam("timestamp", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
.queryParam("v", "2.0");
urlBuilder.queryParam("sign", sign(urlBuilder.getReadParams()));
HttpResponse response = HttpRequest.post(urlBuilder.build(true)).execute();
JSONObject object = JSONObject.parseObject(response.body());
this.checkResponse(object);
JSONObject data = this.getUserDataJsonObject(object);
return AuthUser.builder()
.uuid(authToken.getOpenId())
.username(data.getString("nickname"))
.nickname(data.getString("nickname"))
.avatar(data.getString("imageUrl"))
.gender(AuthUserGender.getRealGender(data.getString("gendar")))
.token(authToken)
.source(source.toString())
.build();
}
/**
* 个人用户无法申请应用
* 暂时只能参考官网给出的返回结果解析
* link: http://open.jd.com/home/home#/doc/api?apiCateId=106&apiId=3051&apiName=jingdong.user.getUserInfoByOpenId
*
* @param object 请求返回结果
* @return data JSONObject
*/
private JSONObject getUserDataJsonObject(JSONObject object) {
return object.getJSONObject("jingdong_user_getUserInfoByOpenId_response")
.getJSONObject("getuserinfobyappidandopenid_result")
.getJSONObject("data");
}
/**
* 宙斯签名规则过程如下:
* 将所有请求参数按照字母先后顺序排列,例如将access_token,app_key,method,timestamp,v 排序为access_token,app_key,method,timestamp,v
* 1.把所有参数名和参数值进行拼接,例如:access_tokenxxxapp_keyxxxmethodxxxxxxtimestampxxxxxxvx
* 2.把appSecret夹在字符串的两端,例如:appSecret+XXXX+appSecret
* 3.使用MD5进行加密,再转化成大写
* link: http://open.jd.com/home/home#/doc/common?listId=890
* link: https://github.com/pingjiang/jd-open-api-sdk-src/blob/master/src/main/java/com/jd/open/api/sdk/DefaultJdClient.java
*
* @param params
* @return
*/
private String sign(Map<String, Object> params) {
// 放入 TreeMap 排序
Map<String, Object> treeMap = new TreeMap<>(params);
String appSecret = config.getClientSecret();
StringBuilder signBuilder = new StringBuilder(appSecret);
for (Map.Entry<String, Object> entry : treeMap.entrySet()) {
String name = entry.getKey();
String value = (String) entry.getValue();
if (StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
signBuilder.append(name).append(value);
}
}
signBuilder.append(appSecret);
try {
return GlobalAuthUtil.jdMd5(signBuilder.toString());
} catch (Exception e) {
throw new AuthException("build sign to jdMd5 error");
}
}
@Override
......@@ -84,6 +170,9 @@ public class AuthJdRequest extends AuthDefaultRequest {
if (object.containsKey("msg")) {
throw new AuthException(object.getString("msg"));
}
if (object.containsKey("error_response")) {
throw new AuthException(object.getJSONObject("error_response").getString("zh_desc"));
}
}
@Override
......
......@@ -238,4 +238,24 @@ public class GlobalAuthUtil {
return null == buffer ? "" : buffer.toString();
}
/**
* 京东md5加密
* link: https://github.com/pingjiang/jd-open-api-sdk-src/blob/master/src/main/java/com/jd/open/api/sdk/internal/util/CodecUtil.java
* @param source
* @return
* @throws Exception
*/
public static String jdMd5(String source) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(source.getBytes(StandardCharsets.UTF_8));
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xff);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
}
......@@ -2,7 +2,6 @@ package me.zhyd.oauth.utils;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Setter;
import java.util.LinkedHashMap;
......@@ -26,6 +25,17 @@ public class UrlBuilder {
}
/**
* 只读的 Map, clone 内部实现也是 putAll
* HashMap#putAll 可实现对 基本类型 和 String 类型的深度复制
*
* @return Map<String, Object>
*/
@SuppressWarnings("unchecked")
public Map<String, Object> getReadParams() {
return (Map<String, Object>) ((LinkedHashMap<String, Object>) params).clone();
}
/**
* @param baseUrl 基础路径
* @return the new {@code UrlBuilder}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册