diff --git a/README.md b/README.md
index 1d0b421b34fad6fde5af206e28c5618990d5f489..9b605cdcd0599807eecd41f78b3688b8af963081 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,7 @@
![](https://gitee.com/yadong.zhang/static/raw/master/JustAuth/huawei.png) |
![](https://gitee.com/yadong.zhang/static/raw/master/JustAuth/wechat.png) |
![](https://gitee.com/yadong.zhang/static/raw/master/JustAuth/csdn.png) |
+ ![](https://qhstatic.kujiale.com/oauth2/images/logo_24.png) |
@@ -157,6 +158,7 @@ authRequest.login(callback);
|
| [AuthHuaweiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthHuaweiRequest.java) | 参考文档 |
|
| [AuthWeChatEnterpriseRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthWeChatEnterpriseRequest.java) | 参考文档 |
|
| [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 无 |
+|
| [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | 参考文档 |
_请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了_
diff --git a/pom.xml b/pom.xml
index e1ead62a64a618f8c33b5a0d71175690e42434e9..7da8895e21ac1a6ee4c0c569baabcafce4c18894 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
JustAuth
https://gitee.com/yadong.zhang/JustAuth
- 史上最全的整合第三方登录的工具,目前已支持Github、Gitee、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软和今日头条等第三方平台的授权登录。
+ 史上最全的整合第三方登录的工具,目前已支持Github、Gitee、酷家乐、微博、钉钉、百度、Coding、腾讯云开发者平台、OSChina、支付宝、QQ、微信、淘宝、Google、Facebook、抖音、领英、小米、微软和今日头条等第三方平台的授权登录。
Login, so easy!
diff --git a/src/main/java/me/zhyd/oauth/config/AuthSource.java b/src/main/java/me/zhyd/oauth/config/AuthSource.java
index 3cd14a16b9b0d69688bf2a23de7feaade163ea01..4ba65993036ac3e263c83b351c25af0cb877299b 100644
--- a/src/main/java/me/zhyd/oauth/config/AuthSource.java
+++ b/src/main/java/me/zhyd/oauth/config/AuthSource.java
@@ -567,6 +567,32 @@ public enum AuthSource {
public String userInfo() {
return "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
}
+ },
+ /**
+ * 酷家乐
+ *
+ * @since 1.10.1
+ */
+ KUJIALE {
+ @Override
+ public String authorize() {
+ return "https://oauth.kujiale.com/oauth2/show";
+ }
+
+ @Override
+ public String accessToken() {
+ return "https://oauth.kujiale.com/oauth2/auth/token";
+ }
+
+ @Override
+ public String userInfo() {
+ return "https://oauth.kujiale.com/oauth2/openapi/user";
+ }
+
+ @Override
+ public String refresh() {
+ return "https://oauth.kujiale.com/oauth2/auth/token/refresh";
+ }
};
/**
diff --git a/src/main/java/me/zhyd/oauth/model/AuthUser.java b/src/main/java/me/zhyd/oauth/model/AuthUser.java
index 59080758588e1542d1e6af43253f490002c181f9..5c85e37be6df9a1af5b48c732f07bad8899fdd55 100644
--- a/src/main/java/me/zhyd/oauth/model/AuthUser.java
+++ b/src/main/java/me/zhyd/oauth/model/AuthUser.java
@@ -66,4 +66,5 @@ public class AuthUser {
* 用户授权的token信息
*/
private AuthToken token;
+
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java b/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..446624a83507a04160c2df8416186e0daddeeba8
--- /dev/null
+++ b/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java
@@ -0,0 +1,130 @@
+package me.zhyd.oauth.request;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSONObject;
+import me.zhyd.oauth.cache.AuthStateCache;
+import me.zhyd.oauth.config.AuthConfig;
+import me.zhyd.oauth.config.AuthSource;
+import me.zhyd.oauth.enums.AuthResponseStatus;
+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.StringUtils;
+import me.zhyd.oauth.utils.UrlBuilder;
+
+/**
+ * @author shahuang
+ * @Date: 2019/8/29 18:50
+ * @since 1.10.1
+ */
+public class AuthKujialeRequest extends AuthDefaultRequest {
+
+ public AuthKujialeRequest(AuthConfig config) {
+ super(config, AuthSource.KUJIALE);
+ }
+
+ public AuthKujialeRequest(AuthConfig config, AuthStateCache authStateCache) {
+ super(config, AuthSource.KUJIALE, authStateCache);
+ }
+
+ /**
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
+ * 默认只向用户请求用户信息授权
+ * @param state state 验证授权流程的参数,可以防止csrf
+ * @return 返回授权地址
+ * @since 1.10.1
+ */
+ @Override
+ public String authorize(String state) {
+ return authorize(state, "get_user_info");
+ }
+
+ /**
+ * 请求授权url
+ * @param state state 验证授权流程的参数,可以防止csrf
+ * @param scopeStr 请求用户授权时向用户显示的可进行授权的列表。如果要填写多个接口名称,请用逗号隔开
+ * 参考https://open.kujiale.com/open/apps/2/docs?doc_id=95#Step1%EF%BC%9A%E8%8E%B7%E5%8F%96Authorization%20Code参数表内的scope字段
+ * @return
+ */
+ public String authorize(String state, String scopeStr) {
+ UrlBuilder urlBuilder = UrlBuilder.fromBaseUrl(source.authorize())
+ .queryParam("response_type", "code")
+ .queryParam("client_id", config.getClientId())
+ .queryParam("redirect_uri", config.getRedirectUri())
+ .queryParam("state", getRealState(state));
+ if (StringUtils.isNotEmpty(scopeStr)) {
+ urlBuilder.queryParam("scope", scopeStr);
+ }
+ return urlBuilder.build();
+ }
+
+ @Override
+ public AuthToken getAccessToken(AuthCallback authCallback) {
+ HttpResponse response = doPostAuthorizationCode(authCallback.getCode());
+ return getAuthToken(response);
+ }
+
+ private AuthToken getAuthToken(HttpResponse response) {
+ String accessTokenStr = response.body();
+ JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
+ if (!"0".equals(accessTokenObject.getString("c"))) {
+ throw new AuthException(accessTokenObject.getString("m"));
+ }
+ JSONObject resultObject = accessTokenObject.getJSONObject("d");
+ return AuthToken.builder()
+ .accessToken(resultObject.getString("accessToken"))
+ .refreshToken(resultObject.getString("refreshToken"))
+ .expireIn(resultObject.getIntValue("expiresIn"))
+ .build();
+ }
+
+ @Override
+ public AuthUser getUserInfo(AuthToken authToken) {
+ String openId = this.getOpenId(authToken);
+ HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl(source.userInfo())
+ .queryParam("access_token", authToken.getAccessToken())
+ .queryParam("open_id", openId)
+ .build()).execute();
+ JSONObject object = JSONObject.parseObject(response.body());
+ if (!"0".equals(object.getString("c"))) {
+ throw new AuthException(object.getString("m"));
+ }
+ JSONObject resultObject = object.getJSONObject("d");
+
+ return AuthUser.builder()
+ .username(resultObject.getString("userName"))
+ .nickname(resultObject.getString("userName"))
+ .avatar(resultObject.getString("avatar"))
+ .uuid(resultObject.getString("openId"))
+ .token(authToken)
+ .source(source)
+ .build();
+ }
+
+ /**
+ * 获取酷家乐的openId,此id在当前client范围内可以唯一识别授权用户
+ *
+ * @param authToken 通过{@link AuthKujialeRequest#getAccessToken(AuthCallback)}获取到的{@code authToken}
+ * @return openId
+ */
+ private String getOpenId(AuthToken authToken) {
+ HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl("https://oauth.kujiale.com/oauth2/auth/user")
+ .queryParam("access_token", authToken.getAccessToken())
+ .build()).execute();
+ String accessTokenStr = response.body();
+ JSONObject accessTokenObject = JSONObject.parseObject(accessTokenStr);
+ if (!"0".equals(accessTokenObject.getString("c"))) {
+ throw new AuthException(accessTokenObject.getString("m"));
+ }
+ return accessTokenObject.getString("d");
+ }
+
+ @Override
+ public AuthResponse refresh(AuthToken authToken) {
+ HttpResponse response = HttpRequest.post(refreshTokenUrl(authToken.getRefreshToken())).execute();
+ return AuthResponse.builder().code(AuthResponseStatus.SUCCESS.getCode()).data(getAuthToken(response)).build();
+ }
+}