diff --git a/README.md b/README.md index 0a5920aff5a272b361786b055098126f3c244364..2d638c7b5efbc8c9f9e369e3244b4aee936082c8 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 6332e38b9a22df8dc089498f94ccc55893a5bcb6..f968e550bd3470901ffce2795b10bc8c9fe34f9a 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 062ca3e3c15bae28249e6f5d75531bbe24fb99d2..d1a57633c83a2ff64c962ae5168aaa43d4be9d40 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 1650aec7fdcd48a0f6125f6b4f4c4ff44f79dcc2..204278af86b9aca382ec310da00aa977ab5863c0 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 b9b9569d0b4cf4e0c96eb9ea1ccd5f8ceee031ba..063e9c8134b475c5e0d1a6f0b63fbc6100183700 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 cdfec4ef69eb4c66d8dbd8d0815aca6ef2cffaba..1f205c75e32981446e049e3479bd1d455bf7535f 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 b9c37843cdcf76cc6001e7da9dd63922023fe67f..a35003ce5d6feac244dd126d8d3fbba8c7f98624 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 9a4bf9593156b7443c77c2cf890ca2e689d0f175..025a70320544c589e229cdd550d9e1e778fca053 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 0b265a258529e63d19e9622e68ae25cb0fcbbabe..5bed3a00c9bcc9e21b55dba55ffb055e8c477489 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 fad5f8ed7df4ab64cd6ccdb0898028b4569e4dc4..1cdf67910ace6d2483b7370e706fb46cce4161cb 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 0000000000000000000000000000000000000000..6b470aae0bdaaaf8fe803af36b32324fec41de39 --- /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 0ea7426648f0ff48abb3b9446cf24a0dd8f7942b..1a6370cbea6588bd3af0a49f9f5edd90eaccf648 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 3f7ddd34c6e4eacbcf96994a8914687c339c4228..1f120e4f58c542c2c9ec10e4c74990c6bb0e4c94 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 0e6c7d32a93fd780cf7c3b041749f52e9a5b14ee..a661e495b746dd962e2a04854ba28c211926bc53 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 508d07111b65ca4c750508ae4e7bc980bf5fe838..44d091fa48cb843beeb84af7abd733d0e5c42bd1 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授权地址 *