From 8520d0b24cb77d07badcbafd26b5e4a2eb949cbe Mon Sep 17 00:00:00 2001 From: "yadong.zhang" Date: Fri, 17 May 2019 10:19:52 +0800 Subject: [PATCH] =?UTF-8?q?:bulb:=20=E4=BF=AE=E6=94=B9=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0QQ=E7=99=BB=E5=BD=95=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- .../java/me/zhyd/oauth/consts/ApiUrl.java | 29 ++++++++ .../zhyd/oauth/request/AuthAlipayRequest.java | 2 + .../zhyd/oauth/request/AuthBaiduRequest.java | 2 + .../zhyd/oauth/request/AuthCodingRequest.java | 2 + .../zhyd/oauth/request/AuthCsdnRequest.java | 2 + .../oauth/request/AuthDingTalkRequest.java | 2 + .../zhyd/oauth/request/AuthGiteeRequest.java | 2 + .../zhyd/oauth/request/AuthGithubRequest.java | 2 + .../oauth/request/AuthOschinaRequest.java | 2 + .../me/zhyd/oauth/request/AuthQqRequest.java | 70 +++++++++++++++++++ .../request/AuthTencentCloudRequest.java | 2 + .../zhyd/oauth/request/AuthWeiboRequest.java | 2 + .../zhyd/oauth/request/BaseAuthRequest.java | 1 + .../java/me/zhyd/oauth/utils/UrlBuilder.java | 51 ++++++++++++++ 15 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/main/java/me/zhyd/oauth/request/AuthQqRequest.java diff --git a/README.md b/README.md index 0a5920a..2d638c7 100644 --- a/README.md +++ b/README.md @@ -101,8 +101,8 @@ authRequest.login("code"); | | [AuthTencentCloudRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java) | 参考文档 | | | [AuthOschinaRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java) | 参考文档 | | | [AuthAlipayRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java) | 参考文档 | +| | [AuthQqRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java) | 参考文档 | | | [AuthCsdnRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java) | 待续 | -| | AuthQqRequest | 参考文档 | | | AuthWechatRequest | 待续 | ## 后续开发计划 @@ -156,11 +156,11 @@ authRequest.login("code"); ![授权支付宝登录](https://images.gitee.com/uploads/images/2019/0327/183654_3d4b94eb_784199.png "授权支付宝登录") -#### 授权csdn +#### 授权qq 待续 -#### 授权qq +#### 授权csdn 待续 diff --git a/src/main/java/me/zhyd/oauth/consts/ApiUrl.java b/src/main/java/me/zhyd/oauth/consts/ApiUrl.java index 6332e38..f968e55 100644 --- a/src/main/java/me/zhyd/oauth/consts/ApiUrl.java +++ b/src/main/java/me/zhyd/oauth/consts/ApiUrl.java @@ -296,6 +296,35 @@ public enum ApiUrl { throw new AuthException(ResponseStatus.UNSUPPORTED); } + @Override + public String refresh() { + throw new AuthException(ResponseStatus.UNSUPPORTED); + } + }, + /** + * QQ + */ + QQ { + @Override + public String authorize() { + return "https://graph.qq.com/oauth2.0/authorize"; + } + + @Override + public String accessToken() { + return "https://graph.qq.com/oauth2.0/token"; + } + + @Override + public String userInfo() { + return "https://graph.qq.com/user/get_user_info"; + } + + @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/request/AuthAlipayRequest.java b/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java index 062ca3e..d1a5763 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java @@ -16,6 +16,8 @@ import me.zhyd.oauth.model.AuthUserGender; import me.zhyd.oauth.utils.StringUtils; /** + * 支付宝登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java index 1650aec..204278a 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java @@ -9,6 +9,8 @@ import me.zhyd.oauth.model.*; import me.zhyd.oauth.utils.UrlBuilder; /** + * 百度账号登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java index b9b9569..063e9c8 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java @@ -11,6 +11,8 @@ import me.zhyd.oauth.model.AuthUserGender; import me.zhyd.oauth.utils.UrlBuilder; /** + * Cooding登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java b/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java index cdfec4e..1f205c7 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java @@ -10,6 +10,8 @@ import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.utils.UrlBuilder; /** + * CSDN登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java index b9c3784..a35003c 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java @@ -15,6 +15,8 @@ import me.zhyd.oauth.utils.UrlBuilder; import java.util.Objects; /** + * 钉钉登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java b/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java index 9a4bf95..025a703 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java @@ -10,6 +10,8 @@ import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.utils.UrlBuilder; /** + * Gitee登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java b/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java index 0b265a2..5bed3a0 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java @@ -13,6 +13,8 @@ import me.zhyd.oauth.utils.UrlBuilder; import java.util.Map; /** + * Github登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java b/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java index fad5f8e..1cdf679 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java @@ -11,6 +11,8 @@ import me.zhyd.oauth.model.AuthUserGender; import me.zhyd.oauth.utils.UrlBuilder; /** + * oschina登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java b/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java new file mode 100644 index 0000000..6b470aa --- /dev/null +++ b/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java @@ -0,0 +1,70 @@ +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.AuthSource; +import me.zhyd.oauth.model.AuthUser; +import me.zhyd.oauth.model.AuthUserGender; +import me.zhyd.oauth.utils.StringUtils; +import me.zhyd.oauth.utils.UrlBuilder; + +/** + * qq登录 + * + * @author yadong.zhang (yadong.zhang0415(a)gmail.com) + * @version 1.0 + * @since 1.8 + */ +public class AuthQqRequest extends BaseAuthRequest { + public AuthQqRequest(AuthConfig config) { + super(config, AuthSource.QQ); + } + + @Override + protected String getAccessToken(String code) { + String accessTokenUrl = UrlBuilder.getQqAccessTokenUrl(config.getClientId(), config.getClientSecret(), code, config.getRedirectUri()); + HttpResponse response = HttpRequest.post(accessTokenUrl).execute(); + JSONObject accessTokenObject = JSONObject.parseObject(response.body()); + if (!accessTokenObject.containsKey("access_token")) { + throw new AuthException("Unable to get token from qq using code [" + code + "]"); + } + return accessTokenObject.getString("access_token"); + } + + @Override + protected AuthUser getUserInfo(String accessToken) { + String openId = this.getOpenId(accessToken); + HttpResponse response = HttpRequest.get(UrlBuilder.getQqUserInfoUrl(accessToken, openId)).execute(); + JSONObject object = JSONObject.parseObject(response.body()); + if (object.getIntValue("ret") != 0) { + throw new AuthException(object.getString("msg")); + } + String avatar = object.getString("figureurl_qq_2"); + if (StringUtils.isEmpty(avatar)) { + avatar = object.getString("figureurl_qq_1"); + } + return AuthUser.builder() + .username(object.getString("nickname")) + .nickname(object.getString("nickname")) + .avatar(avatar) + .gender(AuthUserGender.getRealGender(object.getString("gender"))) + .accessToken(accessToken) + .source(AuthSource.QQ) + .build(); + } + + private String getOpenId(String accessToken) { + HttpResponse response = HttpRequest.get(UrlBuilder.getQqOpenidUrl("https://graph.qq.com/oauth2.0/me", accessToken)).execute(); + if (response.isOk()) { + JSONObject object = JSONObject.parseObject(response.body()); + if (object.containsKey("openid")) { + return object.getString("openid"); + } + throw new AuthException("Invalid openId"); + } + throw new AuthException("Invalid openId"); + } +} diff --git a/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java b/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java index 0ea7426..1a6370c 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java @@ -11,6 +11,8 @@ import me.zhyd.oauth.model.AuthUserGender; import me.zhyd.oauth.utils.UrlBuilder; /** + * 腾讯云登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java b/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java index 3f7ddd3..1f120e4 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java @@ -15,6 +15,8 @@ import me.zhyd.oauth.utils.UrlBuilder; /** + * 微博登录 + * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @version 1.0 * @since 1.8 diff --git a/src/main/java/me/zhyd/oauth/request/BaseAuthRequest.java b/src/main/java/me/zhyd/oauth/request/BaseAuthRequest.java index 0e6c7d3..a661e49 100644 --- a/src/main/java/me/zhyd/oauth/request/BaseAuthRequest.java +++ b/src/main/java/me/zhyd/oauth/request/BaseAuthRequest.java @@ -76,6 +76,7 @@ public abstract class BaseAuthRequest implements AuthRequest { authorizeUrl = UrlBuilder.getAlipayAuthorizeUrl(config.getClientId(), config.getRedirectUri()); break; case QQ: + authorizeUrl = UrlBuilder.getQqAuthorizeUrl(config.getClientId(), config.getRedirectUri()); break; case WECHAT: break; diff --git a/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java b/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java index 508d071..44d091f 100644 --- a/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java +++ b/src/main/java/me/zhyd/oauth/utils/UrlBuilder.java @@ -51,6 +51,11 @@ public class UrlBuilder { private static final String ALIPAY_AUTHORIZE_PATTERN = "{0}?app_id={1}&scope=auth_user&redirect_uri={2}&state=init"; + private static final String QQ_ACCESS_TOKEN_PATTERN = "{0}?client_id={1}&client_secret={2}&grant_type=authorization_code&code={3}&redirect_uri={4}"; + private static final String QQ_USER_INFO_PATTERN = "{0}?access_token={1}&oauth_consumer_key=12345&openid={2}"; + private static final String QQ_AUTHORIZE_PATTERN = "{0}?client_id={1}&response_type=code&redirect_uri={2}&state={3}"; + private static final String QQ_OPENID_PATTERN = "{0}?access_token={1}"; + /** * 获取githubtoken的接口地址 * @@ -354,6 +359,52 @@ public class UrlBuilder { return MessageFormat.format(OSCHINA_AUTHORIZE_PATTERN, ApiUrl.OSCHINA.authorize(), clientId, redirectUrl); } + /** + * 获取qq token的接口地址 + * + * @param clientId qq应用的App Key + * @param clientSecret qq应用的App Secret + * @param code qq授权前的code,用来换token + * @param redirectUri 待跳转的页面 + * @return full url + */ + public static String getQqAccessTokenUrl(String clientId, String clientSecret, String code, String redirectUri) { + return MessageFormat.format(QQ_ACCESS_TOKEN_PATTERN, ApiUrl.QQ.accessToken(), clientId, clientSecret, code, redirectUri); + } + + /** + * 获取qq用户详情的接口地址 + * + * @param token qq 应用的token + * @param openId qq 应用的openId + * @return full url + */ + public static String getQqUserInfoUrl(String token, String openId) { + return MessageFormat.format(QQ_USER_INFO_PATTERN, ApiUrl.QQ.userInfo(), token, openId); + } + + /** + * 获取qq授权地址 + * + * @param clientId qq 应用的Client ID + * @param redirectUrl qq 应用授权成功后的回调地址 + * @return full url + */ + public static String getQqAuthorizeUrl(String clientId, String redirectUrl) { + return MessageFormat.format(QQ_AUTHORIZE_PATTERN, ApiUrl.QQ.authorize(), clientId, redirectUrl, System.currentTimeMillis()); + } + + /** + * 获取qq授权地址 + * + * @param url 获取qqopenid的api接口地址 + * @param token qq 应用授权的token + * @return full url + */ + public static String getQqOpenidUrl(String url, String token) { + return MessageFormat.format(QQ_OPENID_PATTERN, url, token); + } + /** * 获取alipay授权地址 * -- GitLab