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授权地址
*