Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9268f296b | ||
|
|
1c30f6ab2f | ||
|
|
af7baa924c | ||
|
|
9902e7eb0d | ||
|
|
739fa786ce | ||
|
|
6f1cead802 | ||
|
|
374b71e5fe | ||
|
|
9d1ab36e21 | ||
|
|
b8d9f2ebc9 | ||
|
|
c201a9ac90 |
11
README.md
11
README.md
@@ -6,7 +6,7 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://search.maven.org/search?q=JustAuth">
|
||||
<img src="https://img.shields.io/badge/Maven Central-1.7.0-blue.svg" ></img>
|
||||
<img src="https://img.shields.io/badge/Maven Central-1.7.1-blue.svg" ></img>
|
||||
</a>
|
||||
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
|
||||
@@ -14,6 +14,9 @@
|
||||
<a target="_blank" href="https://www.oracle.com/technetwork/java/javase/downloads/index.html">
|
||||
<img src="https://img.shields.io/badge/JDK-1.8+-green.svg" ></img>
|
||||
</a>
|
||||
<a target="_blank" href="https://apidoc.gitee.com/yadong.zhang/JustAuth/">
|
||||
<img src="https://img.shields.io/badge/Docs-1.7.0-orange.svg" ></img>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<center>
|
||||
@@ -65,7 +68,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具
|
||||
<dependency>
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<version>1.7.1</version>
|
||||
</dependency>
|
||||
```
|
||||
- 调用api
|
||||
@@ -94,7 +97,7 @@ authRequest.login("code");
|
||||
|:------:|:-------:|:-------:|
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/gitee.png" width="20"> | [AuthGiteeRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://gitee.com/api/v5/oauth_doc#list_1" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/github.png" width="20"> | [AuthGithubRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://github.com/settings/developers" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/weibo.png" width="20"> | [AuthWeiboRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java) | <a href="https://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/dingtalk.png" width="20"> | [AuthDingTalkRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java) | <a href="https://open-doc.dingtalk.com/microapp/serverapi2/kymkv6" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/baidu.png" width="20"> | [AuthBaiduRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java) | <a href="https://developer.baidu.com/" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/coding.png" width="25"> | [AuthCodingRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java) | <a href="https://open.coding.net/references/oauth/" target="_blank">参考文档</a> |
|
||||
@@ -106,7 +109,7 @@ authRequest.login("code");
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/taobao.png" width="20"> | [AuthTaobaoRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java) | <a href="https://open.taobao.com/doc.htm?spm=a219a.7386797.0.0.4e00669acnkQy6&source=search&docId=105590&docType=1" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/google.png" width="20"> | [AuthGoogleRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java) | <a href="https://developers.google.com/identity/protocols/OpenIDConnect" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/facebook.png" width="20"> | [AuthFacebookRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java) | <a href="https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/douyin.png" width="20"> | [AuthDouyinRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java) | <a href="https://www.douyin.com/platform/doc" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/douyin.png" width="20"> | [AuthDouyinRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java) | <a href="https://www.douyin.com/platform/doc/m-2-1-1" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/linkedin.png" width="20"> | [AuthLinkedinRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java) | <a href="https://docs.microsoft.com/zh-cn/linkedin/shared/authentication/authorization-code-flow?context=linkedin/context" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/microsoft.png" width="20"> | [AuthMicrosoftRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java) | <a href="https://docs.microsoft.com/zh-cn/graph/auth/" target="_blank">参考文档</a> |
|
||||
| <img src="https://gitee.com/yadong.zhang/static/raw/master/JustAuth/mi.png" width="20"> | [AuthMiRequest](https://gitee.com/yadong.zhang/JustAuth/blob/master/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java) | <a href="https://dev.mi.com/console/doc/detail?pId=711" target="_blank">参考文档</a> |
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>me.zhyd.oauth</groupId>
|
||||
<artifactId>JustAuth</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<version>1.7.1</version>
|
||||
|
||||
<name>JustAuth</name>
|
||||
<url>https://gitee.com/yadong.zhang/JustAuth</url>
|
||||
|
||||
@@ -35,4 +35,11 @@ public class AuthConfig {
|
||||
* 支付宝公钥:当选择支付宝登录时,该值可用
|
||||
*/
|
||||
private String alipayPublicKey;
|
||||
|
||||
/**
|
||||
* 是否需要申请unionid,目前只针对qq登录
|
||||
* 注:qq授权登录时,获取unionid需要单独发送邮件申请权限。如果个人开发者账号中申请了该权限,可以将该值置为true,在获取openId时就会同步获取unionId
|
||||
* 参考链接:http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D
|
||||
*/
|
||||
private boolean unionId;
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ public enum AuthSource {
|
||||
|
||||
@Override
|
||||
public String refresh() {
|
||||
return "https://open.douyin.com/oauth/refresh_token";
|
||||
return "https://open.douyin.com/oauth/refresh_token/";
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,7 @@ public class AuthBaiduRequest extends BaseAuthRequest {
|
||||
HttpResponse response = HttpRequest.post(accessTokenUrl).execute();
|
||||
JSONObject accessTokenObject = JSONObject.parseObject(response.body());
|
||||
AuthBaiduErrorCode errorCode = AuthBaiduErrorCode.getErrorCode(accessTokenObject.getString("error"));
|
||||
if (!AuthBaiduErrorCode.OK.equals(errorCode)) {
|
||||
if (AuthBaiduErrorCode.OK != errorCode) {
|
||||
throw new AuthException(errorCode.getDesc());
|
||||
}
|
||||
return AuthToken.builder().accessToken(accessTokenObject.getString("access_token")).build();
|
||||
@@ -42,7 +42,7 @@ public class AuthBaiduRequest extends BaseAuthRequest {
|
||||
String userInfo = response.body();
|
||||
JSONObject object = JSONObject.parseObject(userInfo);
|
||||
AuthBaiduErrorCode errorCode = AuthBaiduErrorCode.getErrorCode(object.getString("error"));
|
||||
if (!AuthBaiduErrorCode.OK.equals(errorCode)) {
|
||||
if (AuthBaiduErrorCode.OK != errorCode) {
|
||||
throw new AuthException(errorCode.getDesc());
|
||||
}
|
||||
return AuthUser.builder()
|
||||
|
||||
@@ -40,13 +40,12 @@ public class AuthDingTalkRequest extends BaseAuthRequest {
|
||||
String urlEncodeSignature = GlobalAuthUtil.generateDingTalkSignature(config.getClientSecret(), timestamp);
|
||||
JSONObject param = new JSONObject();
|
||||
param.put("tmp_auth_code", code);
|
||||
HttpResponse response = HttpRequest.post(UrlBuilder.getDingTalkUserInfoUrl(urlEncodeSignature, timestamp, config.getClientId()))
|
||||
.body(param.toJSONString())
|
||||
.execute();
|
||||
HttpResponse response = HttpRequest.post(UrlBuilder.getDingTalkUserInfoUrl(urlEncodeSignature, timestamp, config
|
||||
.getClientId())).body(param.toJSONString()).execute();
|
||||
String userInfo = response.body();
|
||||
JSONObject object = JSON.parseObject(userInfo);
|
||||
AuthDingTalkErrorCode errorCode = AuthDingTalkErrorCode.getErrorCode(object.getIntValue("errcode"));
|
||||
if (!AuthDingTalkErrorCode.EC0.equals(errorCode)) {
|
||||
if (AuthDingTalkErrorCode.EC0 != errorCode) {
|
||||
throw new AuthException(errorCode.getDesc());
|
||||
}
|
||||
object = object.getJSONObject("user_info");
|
||||
|
||||
@@ -63,7 +63,7 @@ public class AuthMiRequest extends BaseAuthRequest {
|
||||
.execute();
|
||||
|
||||
JSONObject userProfile = JSONObject.parseObject(userResponse.body());
|
||||
if (StrUtil.equalsIgnoreCase(userProfile.getString("result"), "error")) {
|
||||
if ("error".equalsIgnoreCase(userProfile.getString("result"))) {
|
||||
throw new AuthException(userProfile.getString("description"));
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public class AuthMiRequest extends BaseAuthRequest {
|
||||
|
||||
HttpResponse emailResponse = HttpRequest.get(emailPhoneUrl).execute();
|
||||
JSONObject userEmailPhone = JSONObject.parseObject(emailResponse.body());
|
||||
if (!StrUtil.equalsIgnoreCase(userEmailPhone.getString("result"), "error")) {
|
||||
if (!"error".equalsIgnoreCase(userEmailPhone.getString("result"))) {
|
||||
JSONObject emailPhone = userEmailPhone.getJSONObject("data");
|
||||
authUser.setEmail(emailPhone.getString("email"));
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class AuthQqRequest extends BaseAuthRequest {
|
||||
|
||||
private String getOpenId(AuthToken authToken) {
|
||||
String accessToken = authToken.getAccessToken();
|
||||
HttpResponse response = HttpRequest.get(UrlBuilder.getQqOpenidUrl("https://graph.qq.com/oauth2.0/me", accessToken))
|
||||
HttpResponse response = HttpRequest.get(UrlBuilder.getQqOpenidUrl("https://graph.qq.com/oauth2.0/me", accessToken, config.isUnionId()))
|
||||
.execute();
|
||||
if (response.isOk()) {
|
||||
String body = response.body();
|
||||
@@ -97,7 +97,9 @@ public class AuthQqRequest extends BaseAuthRequest {
|
||||
throw new AuthException(object.get("error") + ":" + object.get("error_description"));
|
||||
}
|
||||
authToken.setOpenId(object.getString("openid"));
|
||||
authToken.setUnionId(object.getString("unionid"));
|
||||
if (object.containsKey("unionid")) {
|
||||
authToken.setUnionId(object.getString("unionid"));
|
||||
}
|
||||
return StringUtils.isEmpty(authToken.getUnionId()) ? authToken.getOpenId() : authToken.getUnionId();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@ public class AuthWeiboRequest extends BaseAuthRequest {
|
||||
return AuthToken.builder()
|
||||
.accessToken(accessTokenObject.getString("access_token"))
|
||||
.uid(accessTokenObject.getString("uid"))
|
||||
.expireIn(accessTokenObject.getIntValue("remind_in"))
|
||||
.openId(accessTokenObject.getString("uid"))
|
||||
.expireIn(accessTokenObject.getIntValue("expires_in"))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
@@ -22,16 +24,12 @@ import java.util.Map;
|
||||
* @since 1.8
|
||||
*/
|
||||
public class GlobalAuthUtil {
|
||||
private static final String DEFAULT_ENCODING = "UTF-8";
|
||||
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
|
||||
private static final String ALGORITHM = "HmacSHA256";
|
||||
|
||||
public static String generateDingTalkSignature(String secretKey, String timestamp) {
|
||||
try {
|
||||
byte[] signData = sign(secretKey.getBytes(DEFAULT_ENCODING), timestamp.getBytes(DEFAULT_ENCODING));
|
||||
return urlEncode(new String(Base64.encode(signData, false)));
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new AuthException("Unsupported algorithm: " + DEFAULT_ENCODING, ex);
|
||||
}
|
||||
byte[] signData = sign(secretKey.getBytes(DEFAULT_ENCODING), timestamp.getBytes(DEFAULT_ENCODING));
|
||||
return urlEncode(new String(Base64.encode(signData, false)));
|
||||
}
|
||||
|
||||
private static byte[] sign(byte[] key, byte[] data) {
|
||||
@@ -52,9 +50,8 @@ public class GlobalAuthUtil {
|
||||
}
|
||||
|
||||
try {
|
||||
String encoded = URLEncoder.encode(value, GlobalAuthUtil.DEFAULT_ENCODING);
|
||||
return encoded.replace("+", "%20").replace("*", "%2A")
|
||||
.replace("~", "%7E").replace("/", "%2F");
|
||||
String encoded = URLEncoder.encode(value, GlobalAuthUtil.DEFAULT_ENCODING.displayName());
|
||||
return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AuthException("Failed To Encode Uri", e);
|
||||
}
|
||||
@@ -65,7 +62,7 @@ public class GlobalAuthUtil {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
return URLDecoder.decode(value, GlobalAuthUtil.DEFAULT_ENCODING);
|
||||
return URLDecoder.decode(value, GlobalAuthUtil.DEFAULT_ENCODING.displayName());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new AuthException("Failed To Decode Uri", e);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class UrlBuilder {
|
||||
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}?oauth_consumer_key={1}&access_token={2}&openid={3}";
|
||||
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}&unionid=1";
|
||||
private static final String QQ_OPENID_PATTERN = "{0}?access_token={1}&unionid={2}";
|
||||
|
||||
private static final String WECHAT_AUTHORIZE_PATTERN = "{0}?appid={1}&redirect_uri={2}&response_type=code&scope=snsapi_login&state={3}#wechat_redirect";
|
||||
private static final String WECHAT_ACCESS_TOKEN_PATTERN = "{0}?appid={1}&secret={2}&code={3}&grant_type=authorization_code";
|
||||
@@ -87,7 +87,7 @@ public class UrlBuilder {
|
||||
private static final String MICROSOFT_USER_INFO_PATTERN = "{0}";
|
||||
private static final String MICROSOFT_REFRESH_TOKEN_PATTERN = "{0}?client_id={1}&client_secret={2}&scope=user.read%20mail.read&redirect_uri={3}&refresh_token={4}&grant_type=refresh_token";
|
||||
|
||||
private static final String MI_AUTHORIZE_PATTERN = "{0}?client_id={1}&redirect_uri={2}&response_type=code&scope=user/profile%20user/openIdV2%20user/phoneAndEmail&state={3}&skip_confirm=false";
|
||||
private static final String MI_AUTHORIZE_PATTERN = "{0}?client_id={1}&redirect_uri={2}&response_type=code&scope=1%203%204%206&state={3}&skip_confirm=false";
|
||||
private static final String MI_ACCESS_TOKEN_PATTERN = "{0}?client_id={1}&client_secret={2}&redirect_uri={3}&code={4}&grant_type=authorization_code";
|
||||
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";
|
||||
@@ -438,12 +438,13 @@ public class UrlBuilder {
|
||||
/**
|
||||
* 获取qq授权地址
|
||||
*
|
||||
* @param url 获取qqopenid的api接口地址
|
||||
* @param token qq 应用授权的token
|
||||
* @param url 获取qqopenid的api接口地址
|
||||
* @param token qq 应用授权的token
|
||||
* @param unionid 是否需要获取unionid,默认为false。注:获取unionid需要单独发送邮件申请权限,请个人视情况而定。参考链接:http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D
|
||||
* @return full url
|
||||
*/
|
||||
public static String getQqOpenidUrl(String url, String token) {
|
||||
return MessageFormat.format(QQ_OPENID_PATTERN, url, token);
|
||||
public static String getQqOpenidUrl(String url, String token, boolean unionid) {
|
||||
return MessageFormat.format(QQ_OPENID_PATTERN, url, token, unionid ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
### 2019/06/25
|
||||
qq授权登录时,需要获取`openId`作为`uuid`,在`1.6.1-beta`和`1.7.0`版本中,引入了`unionId`这一属性。获取`unionid`需要单独向qq团队**发送邮件**申请权限,鉴于这一申请权限的步骤比较麻烦(需要填写的内容比较多),所以在`AuthConfig`中增加了一个`unionId`属性,当为**true**时才会获取unionid,当为false时只获取openId。如果你需要该功能, 则在自行申请了相关权限后,将该属性置为true即可。关于unionId的参考链接:[UnionID介绍](http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D)
|
||||
|
||||
### 2019/06/19
|
||||
1. 合并[xkcoding](https://github.com/xkcoding)提交的[PR](https://github.com/zhangyd-c/JustAuth/pull/14),重构了部分代码,jar包由原来的`130+kb`优化到现在的`110+kb`
|
||||
2. 合并[skqing](https://gitee.com/skqing)提交的[PR](https://gitee.com/yadong.zhang/JustAuth/pulls/3), 解决抖音登录失败问题
|
||||
|
||||
Reference in New Issue
Block a user