diff --git a/README.md b/README.md index e027c83..98b08ba 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ + @@ -63,7 +64,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具 me.zhyd.oauth JustAuth - 1.5.1 + 1.6.0 ``` - 调用api @@ -108,6 +109,7 @@ authRequest.login("code"); | | [AuthLinkedinRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java) | 参考文档 | | | [AuthMicrosoftRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java) | 参考文档 | | | [AuthMiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java) | 参考文档 | +| | [AuthToutiaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java) | 参考文档 | | | [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 无 | _请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了_ @@ -135,82 +137,6 @@ _请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经 [阿里妈妈MUX倾力打造的矢量图标库-iconfont](https://www.iconfont.cn/search/index): 本文档中的图标大部分取自该平台 - -## 参考授权图例 - -#### 授权gitee - -![Gitee授权登录](https://images.gitee.com/uploads/images/2019/0221/140015_4c09610e_784199.png "Gitee授权登录") - -#### 授权github - -![Github授权登录](https://images.gitee.com/uploads/images/2019/0221/140032_58f7dfb5_784199.png "Github授权登录") - -#### 授权weibo - -![微博授权登录](https://images.gitee.com/uploads/images/2019/0222/191210_67d5597c_784199.png "微博授权登录") - -#### 授权钉钉 - -![钉钉授权登录](https://images.gitee.com/uploads/images/2019/0221/140540_8da8d959_784199.jpeg "钉钉授权登录") - -#### 授权百度 - -![百度授权登录](https://images.gitee.com/uploads/images/2019/0221/140607_ebf1dcb6_784199.png "百度授权登录") - -#### 授权coding - -![Coding授权登录](https://images.gitee.com/uploads/images/2019/0224/192106_fd53b3d7_784199.png "Coding授权登录") - -#### 授权腾讯云开发者平台 - -![腾讯云开发者平台授权登录](https://images.gitee.com/uploads/images/2019/0224/192128_db9e203b_784199.png "腾讯云开发者平台授权登录") - -#### 授权oschina - -![授权oschina登录](https://images.gitee.com/uploads/images/2019/0322/230652_05b4fd8a_784199.png "授权oschina") - -#### 授权支付宝 - -![授权支付宝登录](https://images.gitee.com/uploads/images/2019/0327/183654_3d4b94eb_784199.png "授权支付宝登录") - -#### 授权qq - -待续 - -#### 授权微信 - -![授权微信登录](https://images.gitee.com/uploads/images/2019/0523/104955_d4cea750_784199.png "授权微信登录") - -#### 授权淘宝 - -![授权淘宝登录](https://images.gitee.com/uploads/images/2019/0518/154604_68b38305_784199.png "授权淘宝登录") - - -#### 授权Google - -![授权google登录](https://images.gitee.com/uploads/images/2019/0521/190650_85c5f1c7_784199.png "授权google登录") - -#### 授权Facebook - -![授权facebook登录](https://images.gitee.com/uploads/images/2019/0521/233647_6a89fb45_784199.png "授权facebook登录") - -#### 授权抖音 - - -#### 授权领英 - -![授权领英登录](https://images.gitee.com/uploads/images/2019/0527/152207_a6342979_784199.png "授权领英登录") - - -#### 授权微软 - -#### 授权小米 - -#### 授权csdn - -_请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了_ - ## 关注&交流 | 公众号 | 微信(备注:加群) | diff --git a/developer.md b/developer.md new file mode 100644 index 0000000..cc649f4 --- /dev/null +++ b/developer.md @@ -0,0 +1,5 @@ +# 项目贡献者名单 + +- · yadong.zhang : [Github] | [Gitee] | [个人网站] +- · yangkai.shen : [Github] | [个人网站] +- 千年等一回,我只为等你... diff --git a/example.md b/example.md new file mode 100644 index 0000000..9aa00b3 --- /dev/null +++ b/example.md @@ -0,0 +1,78 @@ +## 各平台授权页面示例 + +_注:非全部平台,部分平台可能不存在图例_ + +#### 授权gitee + +![Gitee授权登录](https://images.gitee.com/uploads/images/2019/0221/140015_4c09610e_784199.png "Gitee授权登录") + +#### 授权github + +![Github授权登录](https://images.gitee.com/uploads/images/2019/0221/140032_58f7dfb5_784199.png "Github授权登录") + +#### 授权weibo + +![微博授权登录](https://images.gitee.com/uploads/images/2019/0222/191210_67d5597c_784199.png "微博授权登录") + +#### 授权钉钉 + +![钉钉授权登录](https://images.gitee.com/uploads/images/2019/0221/140540_8da8d959_784199.jpeg "钉钉授权登录") + +#### 授权百度 + +![百度授权登录](https://images.gitee.com/uploads/images/2019/0221/140607_ebf1dcb6_784199.png "百度授权登录") + +#### 授权coding + +![Coding授权登录](https://images.gitee.com/uploads/images/2019/0224/192106_fd53b3d7_784199.png "Coding授权登录") + +#### 授权腾讯云开发者平台 + +![腾讯云开发者平台授权登录](https://images.gitee.com/uploads/images/2019/0224/192128_db9e203b_784199.png "腾讯云开发者平台授权登录") + +#### 授权oschina + +![授权oschina登录](https://images.gitee.com/uploads/images/2019/0322/230652_05b4fd8a_784199.png "授权oschina") + +#### 授权支付宝 + +![授权支付宝登录](https://images.gitee.com/uploads/images/2019/0327/183654_3d4b94eb_784199.png "授权支付宝登录") + +#### 授权qq + +待续 + +#### 授权微信 + +![授权微信登录](https://images.gitee.com/uploads/images/2019/0523/104955_d4cea750_784199.png "授权微信登录") + +#### 授权淘宝 + +![授权淘宝登录](https://images.gitee.com/uploads/images/2019/0518/154604_68b38305_784199.png "授权淘宝登录") + + +#### 授权Google + +![授权google登录](https://images.gitee.com/uploads/images/2019/0521/190650_85c5f1c7_784199.png "授权google登录") + +#### 授权Facebook + +![授权facebook登录](https://images.gitee.com/uploads/images/2019/0521/233647_6a89fb45_784199.png "授权facebook登录") + +#### 授权抖音 + + +#### 授权领英 + +![授权领英登录](https://images.gitee.com/uploads/images/2019/0527/152207_a6342979_784199.png "授权领英登录") + + +#### 授权微软 + +#### 授权小米 + +#### 授权今日头条 + +#### 授权csdn + +_请知悉:经咨询CSDN官方客服得知,CSDN的授权开放平台已经下线。如果以前申请过的应用,可以继续使用,但是不再支持申请新的应用。so, 本项目中的CSDN登录只能针对少部分用户使用了_ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 47c84cc..75634bf 100644 --- a/pom.xml +++ b/pom.xml @@ -5,13 +5,13 @@ 4.0.0 me.zhyd.oauth - JustAuth - 1.5.1 + JustAuth-beta + 1.6.0 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/authorization/AuthorizationFactory.java b/src/main/java/me/zhyd/oauth/authorization/AuthorizationFactory.java index bcb941e..c95cdc9 100644 --- a/src/main/java/me/zhyd/oauth/authorization/AuthorizationFactory.java +++ b/src/main/java/me/zhyd/oauth/authorization/AuthorizationFactory.java @@ -71,6 +71,7 @@ public class AuthorizationFactory { AuthorizationFactory.register(AuthSource.LINKEDIN, new LinkedinAuthorization()); AuthorizationFactory.register(AuthSource.MICROSOFT, new MicrosoftAuthorization()); AuthorizationFactory.register(AuthSource.MI, new MiAuthorization()); + AuthorizationFactory.register(AuthSource.TOUTIAO, new ToutiaoAuthorization()); loader = true; } diff --git a/src/main/java/me/zhyd/oauth/authorization/ToutiaoAuthorization.java b/src/main/java/me/zhyd/oauth/authorization/ToutiaoAuthorization.java new file mode 100644 index 0000000..eb110d3 --- /dev/null +++ b/src/main/java/me/zhyd/oauth/authorization/ToutiaoAuthorization.java @@ -0,0 +1,19 @@ +package me.zhyd.oauth.authorization; + +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.utils.UrlBuilder; + +/** + * 今日头条授权 + * + * @author yadong.zhang (yadong.zhang0415(a)gmail.com) + * @version 1.0 + * @since 1.8 + */ +public class ToutiaoAuthorization implements Authorization { + + @Override + public String getAuthorizeUrl(AuthConfig config) { + return UrlBuilder.getToutiaoAuthorizeUrl(config.getClientId(), config.getRedirectUri()); + } +} diff --git a/src/main/java/me/zhyd/oauth/consts/ApiUrl.java b/src/main/java/me/zhyd/oauth/consts/ApiUrl.java index 0125eb5..894bc83 100644 --- a/src/main/java/me/zhyd/oauth/consts/ApiUrl.java +++ b/src/main/java/me/zhyd/oauth/consts/ApiUrl.java @@ -561,6 +561,35 @@ public enum ApiUrl { public String refresh() { return "https://account.xiaomi.com/oauth2/token"; } + }, + /** + * 今日头条 + */ + TOUTIAO { + @Override + public String authorize() { + return "https://open.snssdk.com/auth/authorize"; + } + + @Override + public String accessToken() { + return "https://open.snssdk.com/auth/token"; + } + + @Override + public String userInfo() { + return "https://open.snssdk.com/data/user_profile"; + } + + @Override + public String revoke() { + throw new AuthException(ResponseStatus.UNSUPPORTED); + } + + @Override + public String refresh() { + throw new AuthException(ResponseStatus.UNSUPPORTED); + } }; /** diff --git a/src/main/java/me/zhyd/oauth/model/AuthSource.java b/src/main/java/me/zhyd/oauth/model/AuthSource.java index 33f844e..fa0c375 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthSource.java +++ b/src/main/java/me/zhyd/oauth/model/AuthSource.java @@ -26,5 +26,6 @@ public enum AuthSource { DOUYIN, LINKEDIN, MICROSOFT, - MI + MI, + TOUTIAO } diff --git a/src/main/java/me/zhyd/oauth/model/AuthToutiaoErrorCode.java b/src/main/java/me/zhyd/oauth/model/AuthToutiaoErrorCode.java new file mode 100644 index 0000000..e3f4914 --- /dev/null +++ b/src/main/java/me/zhyd/oauth/model/AuthToutiaoErrorCode.java @@ -0,0 +1,54 @@ +package me.zhyd.oauth.model; + +/** + * 今日头条授权登录时的异常状态码 + * + * @author yadong.zhang (yadong.zhang0415(a)gmail.com) + * @version 1.0 + * @since 1.8 + */ +public enum AuthToutiaoErrorCode { + EC0(0, "接口调用成功"), + EC1(1, "API配置错误,未传入Client Key"), + EC2(2, "API配置错误,Client Key错误,请检查是否和开放平台的ClientKey一致"), + EC3(3, "没有授权信息"), + EC4(4, "响应类型错误"), + EC5(5, "授权类型错误"), + EC6(6, "client_secret错误"), + EC7(7, "authorize_code过期"), + EC8(8, "指定url的scheme不是https"), + EC9(9, "接口内部错误,请联系头条技术"), + EC10(10, "access_token过期"), + EC11(11, "缺少access_token"), + EC12(12, "参数缺失"), + EC13(13, "url错误"), + EC21(21, "域名与登记域名不匹配"), + EC999(999, "未知错误,请联系头条技术"), + ; + + private int code; + private String desc; + + AuthToutiaoErrorCode(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public static AuthToutiaoErrorCode getErrorCode(int errorCode) { + AuthToutiaoErrorCode[] errorCodes = AuthToutiaoErrorCode.values(); + for (AuthToutiaoErrorCode code : errorCodes) { + if (code.getCode() == errorCode) { + return code; + } + } + return EC999; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } +} diff --git a/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java b/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java new file mode 100644 index 0000000..a193b29 --- /dev/null +++ b/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java @@ -0,0 +1,67 @@ +package me.zhyd.oauth.request; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson.JSONObject; +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.exception.AuthException; +import me.zhyd.oauth.model.*; +import me.zhyd.oauth.utils.UrlBuilder; + +/** + * 今日头条登录 + * + * @author yadong.zhang (yadong.zhang0415(a)gmail.com) + * @version 1.5 + * @since 1.5 + */ +public class AuthToutiaoRequest extends BaseAuthRequest { + + public AuthToutiaoRequest(AuthConfig config) { + super(config, AuthSource.TOUTIAO); + } + + @Override + protected AuthToken getAccessToken(String code) { + String accessTokenUrl = UrlBuilder.getToutiaoAccessTokenUrl(config.getClientId(), config.getClientSecret(), code); + HttpResponse response = HttpRequest.get(accessTokenUrl).execute(); + JSONObject object = JSONObject.parseObject(response.body()); + + if (object.containsKey("error_code")) { + throw new AuthException(AuthToutiaoErrorCode.getErrorCode(object.getIntValue("error_code")).getDesc()); + } + + return AuthToken.builder() + .accessToken(object.getString("access_token")) + .expireIn(object.getIntValue("expires_in")) + .openId(object.getString("open_id")) + .build(); + } + + @Override + protected AuthUser getUserInfo(AuthToken authToken) { + HttpResponse userResponse = HttpRequest.get(UrlBuilder.getToutiaoUserInfoUrl(config.getClientId(), authToken.getAccessToken())).execute(); + + JSONObject userProfile = JSONObject.parseObject(userResponse.body()); + + if (userProfile.containsKey("error_code")) { + throw new AuthException(AuthToutiaoErrorCode.getErrorCode(userProfile.getIntValue("error_code")).getDesc()); + } + + JSONObject user = userProfile.getJSONObject("data"); + + boolean isAnonymousUser = user.getIntValue("uid_type") == 14; + String anonymousUserName = "匿名用户"; + + return AuthUser.builder() + .uuid(user.getString("uid")) + .username(isAnonymousUser ? anonymousUserName : user.getString("screen_name")) + .nickname(isAnonymousUser ? anonymousUserName : user.getString("screen_name")) + .avatar(user.getString("avatar_url")) + .remark(user.getString("description")) + .gender(AuthUserGender.getRealGender(user.getString("gender"))) + .token(authToken) + .source(AuthSource.TOUTIAO) + .build(); + } +} diff --git a/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java b/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java index 9372640..a6bebde 100644 --- a/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java +++ b/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java @@ -92,6 +92,10 @@ public class UrlBuilder { private static final String MI_USER_INFO_PATTERN = "{0}?clientId={1}&token={2}"; private static final String MI_REFRESH_TOKEN_PATTERN = "{0}?client_id={1}&client_secret={2}&redirect_uri={3}&refresh_token={4}&grant_type=refresh_token"; + private static final String TOUTIAO_ACCESS_TOKEN_PATTERN = "{0}?client_key={1}&client_secret={2}&code={3}&grant_type=authorize_code"; + private static final String TOUTIAO_USER_INFO_PATTERN = "{0}?client_key={1}&access_token={2}"; + private static final String TOUTIAO_AUTHORIZE_PATTERN = "{0}?client_key={1}&redirect_uri={2}&state={3}&response_type=code&auth_only=1&display=0"; + /** * 获取githubtoken的接口地址 * @@ -776,4 +780,38 @@ public class UrlBuilder { public static String getMiRefreshUrl(String clientId, String clientSecret, String redirectUrl, String refreshToken) { return MessageFormat.format(MI_REFRESH_TOKEN_PATTERN, ApiUrl.MI.refresh(), clientId, clientSecret, redirectUrl, refreshToken); } + + /** + * 获取今日头条授权地址 + * + * @param clientId 今日头条 应用的Client ID + * @param redirectUrl 今日头条 应用授权成功后的回调地址 + * @return full url + */ + public static String getToutiaoAuthorizeUrl(String clientId, String redirectUrl) { + return MessageFormat.format(TOUTIAO_AUTHORIZE_PATTERN, ApiUrl.TOUTIAO.authorize(), clientId, redirectUrl, System.currentTimeMillis()); + } + + /** + * 获取今日头条 token的接口地址 + * + * @param clientId 今日头条 应用的Client ID + * @param clientSecret 今日头条 应用的Client Secret + * @param code 今日头条 授权前的code,用来换token + * @return full url + */ + public static String getToutiaoAccessTokenUrl(String clientId, String clientSecret, String code) { + return MessageFormat.format(TOUTIAO_ACCESS_TOKEN_PATTERN, ApiUrl.TOUTIAO.accessToken(), clientId, clientSecret, code); + } + + /** + * 获取今日头条用户详情的接口地址 + * + * @param clientId 今日头条 应用的client_key + * @param token token + * @return full url + */ + public static String getToutiaoUserInfoUrl(String clientId, String token) { + return MessageFormat.format(TOUTIAO_USER_INFO_PATTERN, ApiUrl.TOUTIAO.userInfo(), clientId, token); + } } diff --git a/update.md b/update.md index 534a047..7c85527 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +### 2019/06/06 +1. 增加今日头条的授权登陆 +2. 发布1.6.0-beta版本,今日头条开发者暂时不能认证, 所以无法做测试,等测试通过后,正式发布release版本 + ### 2019/05/28 1. 增加小米账号和微软的授权登陆 2. 发布1.5.0版本