From de273d0482193b7bf3fc5e06b03b24b31b0236ec Mon Sep 17 00:00:00 2001 From: shahuang Date: Fri, 30 Aug 2019 16:28:43 +0800 Subject: [PATCH 1/4] add kujiale auth --- pom.xml | 2 +- .../java/me/zhyd/oauth/config/AuthSource.java | 26 ++++ .../java/me/zhyd/oauth/model/AuthUser.java | 14 ++ .../oauth/request/AuthKujialeRequest.java | 140 ++++++++++++++++++ 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java diff --git a/pom.xml b/pom.xml index e1ead62..7da8895 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 3cd14a1..4ba6599 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 5908075..2604dc6 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthUser.java +++ b/src/main/java/me/zhyd/oauth/model/AuthUser.java @@ -66,4 +66,18 @@ public class AuthUser { * 用户授权的token信息 */ private AuthToken token; + + /** + * 用户在平台上的用户类型(类似是C类用户或者B类用户,或者各个平台自己的细分分类) + */ + private Integer userType; + /** + * 在平台上是否为VIP + */ + private Boolean isVip; + + /** + * 所属平台组织的唯一识别id + */ + private String organizationUuid; } 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 0000000..b65d403 --- /dev/null +++ b/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java @@ -0,0 +1,140 @@ +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"); + + JSONObject extraInfoObject = object.getJSONObject("extraInfo"); + boolean isVip = false; + String organizationUuid = null; + if (extraInfoObject != null) { + isVip = extraInfoObject.getBoolean("isVip"); + organizationUuid = extraInfoObject.getString("partnerId"); + } + + return AuthUser.builder() + .username(resultObject.getString("userName")) + .nickname(resultObject.getString("userName")) + .avatar(resultObject.getString("avatar")) + .uuid(resultObject.getString("openId")) + .isVip(isVip) + .organizationUuid(organizationUuid) + .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(); + } +} From ff48e107c8d79a5bfd65736e5270191b6757cf7d Mon Sep 17 00:00:00 2001 From: wuweiqi1993 <32814990+wuweiqi1993@users.noreply.github.com> Date: Fri, 30 Aug 2019 16:36:21 +0800 Subject: [PATCH 2/4] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5cd83fd..48078ca 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ + @@ -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登录只能针对少部分用户使用了_ From 13a388fb0f36c6b5a89900bf81a2f223b7d76840 Mon Sep 17 00:00:00 2001 From: wuweiqi1993 <32814990+wuweiqi1993@users.noreply.github.com> Date: Fri, 30 Aug 2019 16:37:29 +0800 Subject: [PATCH 3/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48078ca..59c8bb4 100644 --- a/README.md +++ b/README.md @@ -158,7 +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) | 无 | +| | [AuthKujialeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java) | 参考文档 | _请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了_ From bb975f8eb319f878260ef0a6ff469cee4556c0e0 Mon Sep 17 00:00:00 2001 From: shahuang Date: Mon, 2 Sep 2019 11:24:59 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E9=A2=9D=E5=A4=96=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/me/zhyd/oauth/model/AuthUser.java | 13 ------------- .../me/zhyd/oauth/request/AuthKujialeRequest.java | 10 ---------- 2 files changed, 23 deletions(-) diff --git a/src/main/java/me/zhyd/oauth/model/AuthUser.java b/src/main/java/me/zhyd/oauth/model/AuthUser.java index 2604dc6..5c85e37 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthUser.java +++ b/src/main/java/me/zhyd/oauth/model/AuthUser.java @@ -67,17 +67,4 @@ public class AuthUser { */ private AuthToken token; - /** - * 用户在平台上的用户类型(类似是C类用户或者B类用户,或者各个平台自己的细分分类) - */ - private Integer userType; - /** - * 在平台上是否为VIP - */ - private Boolean isVip; - - /** - * 所属平台组织的唯一识别id - */ - private String organizationUuid; } diff --git a/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java b/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java index b65d403..446624a 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthKujialeRequest.java @@ -94,21 +94,11 @@ public class AuthKujialeRequest extends AuthDefaultRequest { } JSONObject resultObject = object.getJSONObject("d"); - JSONObject extraInfoObject = object.getJSONObject("extraInfo"); - boolean isVip = false; - String organizationUuid = null; - if (extraInfoObject != null) { - isVip = extraInfoObject.getBoolean("isVip"); - organizationUuid = extraInfoObject.getString("partnerId"); - } - return AuthUser.builder() .username(resultObject.getString("userName")) .nickname(resultObject.getString("userName")) .avatar(resultObject.getString("avatar")) .uuid(resultObject.getString("openId")) - .isVip(isVip) - .organizationUuid(organizationUuid) .token(authToken) .source(source) .build();