1
0
mirror of synced 2025-12-20 22:35:51 +08:00

Compare commits

..

16 Commits

Author SHA1 Message Date
yadong.zhang
cf74f811fa 📝 编写文档 2019-06-19 20:01:03 +08:00
yadong.zhang
65daa0592a 🚑 增加alipay授权参数的验证,修改部分命名 2019-06-19 16:48:09 +08:00
yadong.zhang
25424023c4 🔀 合并代码 2019-06-19 10:10:20 +08:00
yadong.zhang
67579bfb07 🍻 qq登录时根据openid和unionid选择合适的值作为uuid 2019-06-19 10:06:15 +08:00
yadong.zhang
458de3840d Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java
#	src/main/java/me/zhyd/oauth/request/AuthQqRequest.java
2019-06-19 10:04:47 +08:00
yadong.zhang
1c1d2dc9db !2 修复最近提出一些问题和BUG
Merge pull request !2 from skqing/master
2019-06-19 10:01:59 +08:00
yadong.zhang
f5de7f93b5 🍻 解决Issue #IY1QR 增加对Config属性的校验功能,主要校验redirect uri的合法性 2019-06-19 09:56:28 +08:00
skqing
dcf5f30e61 修复以下问题:
QQ登录未获取真正的uuid
部分Request封装AuthUser时缺少gender属性
location属性设置方式不一致
钉钉登录获取用户信息忽略了openid
钉钉登录回调报错 bug
2019-06-19 09:51:43 +08:00
yadong.zhang
e534a4b62e 🍻 解决Issue #IY2FV 2019-06-18 19:56:00 +08:00
yadong.zhang
42ede32fc5 🍻 醉酒写代码 2019-06-18 19:51:53 +08:00
yadong.zhang
c0dd700b0a 🎨 解决Issue #IY2OH 2019-06-18 19:27:11 +08:00
yadong.zhang
f32c341b63 🎨 解决Issue #IY2HW 2019-06-18 19:21:05 +08:00
yadong.zhang
82358cbddb !1 修复钉钉回调JSON解析用户信息异常问题
Merge pull request !1 from skqing/master
2019-06-18 19:04:18 +08:00
skqing
56df9bc1b0 针对钉钉登录增加AuthToken属性 2019-06-18 14:55:28 +08:00
skqing
438660621e 解决钉钉回调异常问题 https://gitee.com/yadong.zhang/JustAuth/issues/IY1Z3 2019-06-18 14:20:05 +08:00
yadong.zhang
937fba37f5 📝 编写文档 2019-06-06 19:35:58 +08:00
24 changed files with 128 additions and 52 deletions

View File

@@ -6,7 +6,7 @@
</p> </p>
<p align="center"> <p align="center">
<a target="_blank" href="https://search.maven.org/search?q=JustAuth"> <a target="_blank" href="https://search.maven.org/search?q=JustAuth">
<img src="https://img.shields.io/badge/Maven Central-1.5.1-blue.svg" ></img> <img src="https://img.shields.io/badge/Maven Central-1.6.1_beta-blue.svg" ></img>
</a> </a>
<a target="_blank" href="https://gitee.com/yadong.zhang/JustAuth/blob/master/LICENSE"> <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> <img src="https://img.shields.io/apm/l/vim-mode.svg?color=yellow" ></img>
@@ -64,7 +64,7 @@ JustAuth如你所见它仅仅是一个**第三方授权登录**的**工具
<dependency> <dependency>
<groupId>me.zhyd.oauth</groupId> <groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> <artifactId>JustAuth</artifactId>
<version>1.6.0-beta</version> <version>1.6.1-beta</version>
</dependency> </dependency>
``` ```
- 调用api - 调用api

View File

@@ -6,7 +6,7 @@
<groupId>me.zhyd.oauth</groupId> <groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> <artifactId>JustAuth</artifactId>
<version>1.6.0-beta</version> <version>1.6.1-beta</version>
<name>JustAuth</name> <name>JustAuth</name>
<url>https://gitee.com/yadong.zhang/JustAuth</url> <url>https://gitee.com/yadong.zhang/JustAuth</url>

View File

@@ -10,7 +10,7 @@ import java.util.Map;
/** /**
* 授权工厂类,负责创建指定平台的授权类获取授权地址 * 授权工厂类,负责创建指定平台的授权类获取授权地址
* <p> * <p>
* 使用策略模式 + 工厂模式 避免大量的if elseswatch操作 * 使用策略模式 + 工厂模式 避免大量的if elseswitch操作
* *
* @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @version 1.0 * @version 1.0

View File

@@ -19,6 +19,7 @@ public class AuthToken {
private String uid; private String uid;
private String openId; private String openId;
private String accessCode; private String accessCode;
private String unionId;
/** /**
* Google附带属性 * Google附带属性

View File

@@ -10,7 +10,7 @@ import java.util.Arrays;
* @since 1.8 * @since 1.8
*/ */
public enum AuthUserGender { public enum AuthUserGender {
MALE(1, ""), FEMALE(0, ""), UNKNOW(-1, ""); MALE(1, ""), FEMALE(0, ""), UNKNOW(-1, "未知");
private int code; private int code;
private String desc; private String desc;

View File

@@ -67,14 +67,17 @@ public class AuthAlipayRequest extends BaseAuthRequest {
if (!response.isSuccess()) { if (!response.isSuccess()) {
throw new AuthException(response.getSubMsg()); throw new AuthException(response.getSubMsg());
} }
String province = response.getProvince(), String province = response.getProvince(),
city = response.getCity(); city = response.getCity();
String location = String.format("%s %s", StringUtils.isEmpty(province) ? "" : province, StringUtils.isEmpty(city) ? "" : city);
return AuthUser.builder() return AuthUser.builder()
.uuid(response.getUserId()) .uuid(response.getUserId())
.username(StringUtils.isEmpty(response.getUserName()) ? response.getNickName() : response.getUserName()) .username(StringUtils.isEmpty(response.getUserName()) ? response.getNickName() : response.getUserName())
.nickname(response.getNickName()) .nickname(response.getNickName())
.avatar(response.getAvatar()) .avatar(response.getAvatar())
.location(String.format("%s %s", StringUtils.isEmpty(province) ? "" : province, StringUtils.isEmpty(city) ? "" : city)) .location(location)
.gender(AuthUserGender.getRealGender(response.getGender())) .gender(AuthUserGender.getRealGender(response.getGender()))
.token(authToken) .token(authToken)
.source(AuthSource.ALIPAY) .source(AuthSource.ALIPAY)

View File

@@ -45,6 +45,7 @@ public class AuthCodingRequest extends BaseAuthRequest {
if (object.getIntValue("code") != 0) { if (object.getIntValue("code") != 0) {
throw new AuthException(object.getString("msg")); throw new AuthException(object.getString("msg"));
} }
object = object.getJSONObject("data"); object = object.getJSONObject("data");
return AuthUser.builder() return AuthUser.builder()
.uuid(object.getString("id")) .uuid(object.getString("id"))

View File

@@ -8,6 +8,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthSource; import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.model.AuthUserGender;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
/** /**
@@ -49,6 +50,7 @@ public class AuthCsdnRequest extends BaseAuthRequest {
.username(object.getString("username")) .username(object.getString("username"))
.remark(object.getString("description")) .remark(object.getString("description"))
.blog(object.getString("website")) .blog(object.getString("website"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.CSDN) .source(AuthSource.CSDN)
.build(); .build();

View File

@@ -2,18 +2,14 @@ package me.zhyd.oauth.request;
import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthDingTalkErrorCode; import me.zhyd.oauth.model.*;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.GlobalAuthUtil; import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
import java.util.Objects;
/** /**
* 钉钉登录 * 钉钉登录
* *
@@ -38,23 +34,31 @@ public class AuthDingTalkRequest extends BaseAuthRequest {
protected AuthUser getUserInfo(AuthToken authToken) { protected AuthUser getUserInfo(AuthToken authToken) {
String code = authToken.getAccessCode(); String code = authToken.getAccessCode();
// 根据timestamp, appSecret计算签名值 // 根据timestamp, appSecret计算签名值
String stringToSign = System.currentTimeMillis() + ""; String timestamp = System.currentTimeMillis() + "";
String urlEncodeSignature = GlobalAuthUtil.generateDingTalkSignature(config.getClientSecret(), stringToSign); String urlEncodeSignature = GlobalAuthUtil.generateDingTalkSignature(config.getClientSecret(), timestamp);
HttpResponse response = HttpRequest.post(UrlBuilder.getDingTalkUserInfoUrl(urlEncodeSignature, stringToSign, config.getClientId())) JSONObject param = new JSONObject();
.body(Objects.requireNonNull(new JSONObject().put("tmp_auth_code", code))) param.put("tmp_auth_code", code);
HttpResponse response = HttpRequest.post(UrlBuilder.getDingTalkUserInfoUrl(urlEncodeSignature, timestamp, config.getClientId()))
.body(param.toJSONString())
.execute(); .execute();
String userInfo = response.body(); String userInfo = response.body();
JSONObject object = new JSONObject(userInfo); JSONObject object = JSON.parseObject(userInfo);
AuthDingTalkErrorCode errorCode = AuthDingTalkErrorCode.getErrorCode(object.getInt("errcode")); AuthDingTalkErrorCode errorCode = AuthDingTalkErrorCode.getErrorCode(object.getIntValue("errcode"));
if (!AuthDingTalkErrorCode.EC0.equals(errorCode)) { if (!AuthDingTalkErrorCode.EC0.equals(errorCode)) {
throw new AuthException(errorCode.getDesc()); throw new AuthException(errorCode.getDesc());
} }
object = object.getJSONObject("user_info"); object = object.getJSONObject("user_info");
AuthToken token = AuthToken.builder()
.openId(object.getString("openid"))
.unionId(object.getString("unionid"))
.build();
return AuthUser.builder() return AuthUser.builder()
.uuid(object.getStr("openid")) .uuid(object.getString("unionid"))
.nickname(object.getStr("nick")) .nickname(object.getString("nick"))
.username(object.getStr("nick")) .username(object.getString("nick"))
.gender(AuthUserGender.UNKNOW)
.source(AuthSource.DINGTALK) .source(AuthSource.DINGTALK)
.token(token)
.build(); .build();
} }
} }

View File

@@ -5,10 +5,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.*;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
@@ -45,6 +42,7 @@ public class AuthDouyinRequest extends BaseAuthRequest {
.username(userInfoObject.getString("nickname")) .username(userInfoObject.getString("nickname"))
.nickname(userInfoObject.getString("nickname")) .nickname(userInfoObject.getString("nickname"))
.avatar(userInfoObject.getString("avatar")) .avatar(userInfoObject.getString("avatar"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.DOUYIN) .source(AuthSource.DOUYIN)
.build(); .build();

View File

@@ -8,6 +8,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthSource; import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.model.AuthUserGender;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
/** /**
@@ -52,6 +53,7 @@ public class AuthGiteeRequest extends BaseAuthRequest {
.location(object.getString("address")) .location(object.getString("address"))
.email(object.getString("email")) .email(object.getString("email"))
.remark(object.getString("bio")) .remark(object.getString("bio"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.GITEE) .source(AuthSource.GITEE)
.build(); .build();

View File

@@ -8,6 +8,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthSource; import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.model.AuthUserGender;
import me.zhyd.oauth.utils.GlobalAuthUtil; import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
@@ -55,6 +56,7 @@ public class AuthGithubRequest extends BaseAuthRequest {
.location(object.getString("location")) .location(object.getString("location"))
.email(object.getString("email")) .email(object.getString("email"))
.remark(object.getString("bio")) .remark(object.getString("bio"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.GITHUB) .source(AuthSource.GITHUB)
.build(); .build();

View File

@@ -8,6 +8,7 @@ import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthSource; import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser; import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.model.AuthUserGender;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
/** /**
@@ -57,6 +58,7 @@ public class AuthGoogleRequest extends BaseAuthRequest {
.nickname(object.getString("name")) .nickname(object.getString("name"))
.location(object.getString("locale")) .location(object.getString("locale"))
.email(object.getString("email")) .email(object.getString("email"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.GOOGLE) .source(AuthSource.GOOGLE)
.build(); .build();

View File

@@ -6,10 +6,7 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.*;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.StringUtils; import me.zhyd.oauth.utils.StringUtils;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
@@ -81,6 +78,7 @@ public class AuthLinkedinRequest extends BaseAuthRequest {
.avatar(avatar) .avatar(avatar)
.email(email) .email(email)
.token(authToken) .token(authToken)
.gender(AuthUserGender.UNKNOW)
.source(AuthSource.LINKEDIN) .source(AuthSource.LINKEDIN)
.build(); .build();
} }

View File

@@ -6,10 +6,7 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.*;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
import java.text.MessageFormat; import java.text.MessageFormat;
@@ -74,6 +71,7 @@ public class AuthMiRequest extends BaseAuthRequest {
.nickname(user.getString("miliaoNick")) .nickname(user.getString("miliaoNick"))
.avatar(user.getString("miliaoIcon")) .avatar(user.getString("miliaoIcon"))
.email(user.getString("mail")) .email(user.getString("mail"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.MI) .source(AuthSource.MI)
.build(); .build();

View File

@@ -6,10 +6,7 @@ import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthResponse; import me.zhyd.oauth.model.*;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.UrlBuilder; import me.zhyd.oauth.utils.UrlBuilder;
import java.util.HashMap; import java.util.HashMap;
@@ -85,6 +82,7 @@ public class AuthMicrosoftRequest extends BaseAuthRequest {
.nickname(object.getString("displayName")) .nickname(object.getString("displayName"))
.location(object.getString("officeLocation")) .location(object.getString("officeLocation"))
.email(object.getString("mail")) .email(object.getString("mail"))
.gender(AuthUserGender.UNKNOW)
.token(authToken) .token(authToken)
.source(AuthSource.MICROSOFT) .source(AuthSource.MICROSOFT)
.build(); .build();

View File

@@ -48,7 +48,7 @@ public class AuthQqRequest extends BaseAuthRequest {
@Override @Override
protected AuthUser getUserInfo(AuthToken authToken) { protected AuthUser getUserInfo(AuthToken authToken) {
String accessToken = authToken.getAccessToken(); String accessToken = authToken.getAccessToken();
String openId = this.getOpenId(accessToken); String openId = this.getOpenId(authToken);
HttpResponse response = HttpRequest.get(UrlBuilder.getQqUserInfoUrl(config.getClientId(), accessToken, openId)) HttpResponse response = HttpRequest.get(UrlBuilder.getQqUserInfoUrl(config.getClientId(), accessToken, openId))
.execute(); .execute();
JSONObject object = JSONObject.parseObject(response.body()); JSONObject object = JSONObject.parseObject(response.body());
@@ -59,11 +59,13 @@ public class AuthQqRequest extends BaseAuthRequest {
if (StringUtils.isEmpty(avatar)) { if (StringUtils.isEmpty(avatar)) {
avatar = object.getString("figureurl_qq_1"); avatar = object.getString("figureurl_qq_1");
} }
String location = String.format("%s-%s", object.getString("province"), object.getString("city"));
return AuthUser.builder() return AuthUser.builder()
.username(object.getString("nickname")) .username(object.getString("nickname"))
.nickname(object.getString("nickname")) .nickname(object.getString("nickname"))
.avatar(avatar) .avatar(avatar)
.location(object.getString("province") + "-" + object.getString("city")) .location(location)
.uuid(openId) .uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("gender"))) .gender(AuthUserGender.getRealGender(object.getString("gender")))
.token(authToken) .token(authToken)
@@ -71,7 +73,8 @@ public class AuthQqRequest extends BaseAuthRequest {
.build(); .build();
} }
private String getOpenId(String accessToken) { 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))
.execute(); .execute();
if (response.isOk()) { if (response.isOk()) {
@@ -80,11 +83,14 @@ public class AuthQqRequest extends BaseAuthRequest {
String removeSuffix = StrUtil.replace(removePrefix, ");", ""); String removeSuffix = StrUtil.replace(removePrefix, ");", "");
String openId = StrUtil.trim(removeSuffix); String openId = StrUtil.trim(removeSuffix);
JSONObject object = JSONObject.parseObject(openId); JSONObject object = JSONObject.parseObject(openId);
if (object.containsKey("openid")) { if (object.containsKey("error")) {
return object.getString("openid"); throw new AuthException(object.get("error") + ":" + object.get("error_description"));
} }
throw new AuthException("Invalid openId"); authToken.setOpenId(object.getString("openid"));
authToken.setUnionId(object.getString("unionid"));
return StringUtils.isEmpty(authToken.getUnionId()) ? authToken.getOpenId() : authToken.getUnionId();
} }
throw new AuthException("Invalid openId");
throw new AuthException("request error");
} }
} }

View File

@@ -42,11 +42,12 @@ public class AuthWeChatRequest extends BaseAuthRequest {
this.checkResponse(object); this.checkResponse(object);
String location = String.format("%s-%s-%s", object.getString("country"), object.getString("province"), object.getString("city"));
return AuthUser.builder() return AuthUser.builder()
.username(object.getString("nickname")) .username(object.getString("nickname"))
.nickname(object.getString("nickname")) .nickname(object.getString("nickname"))
.avatar(object.getString("headimgurl")) .avatar(object.getString("headimgurl"))
.location(object.getString("country") + "-" + object.getString("province") + "-" + object.getString("city")) .location(location)
.uuid(openId) .uuid(openId)
.gender(AuthUserGender.getRealGender(object.getString("sex"))) .gender(AuthUserGender.getRealGender(object.getString("sex")))
.token(authToken) .token(authToken)
@@ -73,6 +74,7 @@ public class AuthWeChatRequest extends BaseAuthRequest {
throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg")); throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg"));
} }
} }
/** /**
* 获取token适用于获取access_token和刷新token * 获取token适用于获取access_token和刷新token
* *

View File

@@ -23,9 +23,11 @@ public abstract class BaseAuthRequest implements AuthRequest {
public BaseAuthRequest(AuthConfig config, AuthSource source) { public BaseAuthRequest(AuthConfig config, AuthSource source) {
this.config = config; this.config = config;
this.source = source; this.source = source;
if (!AuthConfigChecker.isSupportedAuth(config)) { if (!AuthConfigChecker.isSupportedAuth(config, source)) {
throw new AuthException(ResponseStatus.PARAMETER_INCOMPLETE); throw new AuthException(ResponseStatus.PARAMETER_INCOMPLETE);
} }
// 校验配置合法性
AuthConfigChecker.check(config, source);
} }
protected abstract AuthToken getAccessToken(String code); protected abstract AuthToken getAccessToken(String code);

View File

@@ -13,6 +13,7 @@ public enum ResponseStatus {
UNSUPPORTED(5003, "Unsupported operation"), UNSUPPORTED(5003, "Unsupported operation"),
NO_AUTH_SOURCE(5004, "AuthSource cannot be null"), NO_AUTH_SOURCE(5004, "AuthSource cannot be null"),
UNIDENTIFIED_PLATFORM(5005, "Unidentified platform"), UNIDENTIFIED_PLATFORM(5005, "Unidentified platform"),
ILLEGAL_REDIRECT_URI(5006, "Illegal redirect uri"),
; ;
private int code; private int code;

View File

@@ -1,6 +1,9 @@
package me.zhyd.oauth.utils; package me.zhyd.oauth.utils;
import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthSource;
import me.zhyd.oauth.request.ResponseStatus;
/** /**
* 授权配置类的校验器 * 授权配置类的校验器
@@ -15,9 +18,35 @@ public class AuthConfigChecker {
* 是否支持第三方登录 * 是否支持第三方登录
* *
* @param config config * @param config config
* @param source source
* @return true or false * @return true or false
*/ */
public static boolean isSupportedAuth(AuthConfig config) { public static boolean isSupportedAuth(AuthConfig config, AuthSource source) {
return StringUtils.isNotEmpty(config.getClientId()) && StringUtils.isNotEmpty(config.getClientSecret()) && StringUtils.isNotEmpty(config.getRedirectUri()); boolean isSupported = StringUtils.isNotEmpty(config.getClientId()) && StringUtils.isNotEmpty(config.getClientSecret()) && StringUtils.isNotEmpty(config.getRedirectUri());
if (isSupported && AuthSource.ALIPAY == source) {
isSupported = StringUtils.isNotEmpty(config.getAlipayPublicKey());
}
return isSupported;
}
/**
* 检查配置合法性。针对部分平台, 对redirect uri有特定要求。一般来说redirect uri都是http://而对于facebook平台 redirect uri 必须是https的链接
*
* @param config config
* @param source source
*/
public static void check(AuthConfig config, AuthSource source) {
String redirectUri = config.getRedirectUri();
if (!GlobalAuthUtil.isHttpProtocol(redirectUri) && !GlobalAuthUtil.isHttpsProtocol(redirectUri)) {
throw new AuthException(ResponseStatus.ILLEGAL_REDIRECT_URI);
}
// facebook的回调地址必须为https的链接
if (AuthSource.FACEBOOK == source && !GlobalAuthUtil.isHttpsProtocol(redirectUri)) {
throw new AuthException(ResponseStatus.ILLEGAL_REDIRECT_URI);
}
// 支付宝在创建回调地址时不允许使用localhost或者127.0.0.1
if (AuthSource.ALIPAY == source && GlobalAuthUtil.isLocalHost(redirectUri)) {
throw new AuthException(ResponseStatus.ILLEGAL_REDIRECT_URI);
}
} }
} }

View File

@@ -25,9 +25,9 @@ public class GlobalAuthUtil {
private static final String DEFAULT_ENCODING = "UTF-8"; private static final String DEFAULT_ENCODING = "UTF-8";
private static final String ALGORITHM = "HmacSHA256"; private static final String ALGORITHM = "HmacSHA256";
public static String generateDingTalkSignature(String canonicalString, String secret) { public static String generateDingTalkSignature(String secretKey, String timestamp) {
try { try {
byte[] signData = sign(canonicalString.getBytes(DEFAULT_ENCODING), secret.getBytes(DEFAULT_ENCODING)); byte[] signData = sign(secretKey.getBytes(DEFAULT_ENCODING), timestamp.getBytes(DEFAULT_ENCODING));
return urlEncode(new String(Base64.encode(signData, false))); return urlEncode(new String(Base64.encode(signData, false)));
} catch (UnsupportedEncodingException ex) { } catch (UnsupportedEncodingException ex) {
throw new AuthException("Unsupported algorithm: " + DEFAULT_ENCODING, ex); throw new AuthException("Unsupported algorithm: " + DEFAULT_ENCODING, ex);
@@ -84,4 +84,23 @@ public class GlobalAuthUtil {
} }
return res; return res;
} }
public static boolean isHttpProtocol(String url) {
if (StringUtils.isEmpty(url)) {
return false;
}
return url.startsWith("http://");
}
public static boolean isHttpsProtocol(String url) {
if (StringUtils.isEmpty(url)) {
return false;
}
return url.startsWith("https://");
}
public static boolean isLocalHost(String url) {
return StringUtils.isEmpty(url) || url.contains("127.0.0.1") || url.contains("localhost");
}
} }

View File

@@ -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_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_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_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}"; private static final String QQ_OPENID_PATTERN = "{0}?access_token={1}&unionid=1";
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_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"; private static final String WECHAT_ACCESS_TOKEN_PATTERN = "{0}?appid={1}&secret={2}&code={3}&grant_type=authorization_code";

View File

@@ -1,3 +1,11 @@
### 2019/06/18
1. 解决Issue [#IY2HW](https://gitee.com/yadong.zhang/JustAuth/issues/IY2HW)
2. 解决Issue [#IY2OH](https://gitee.com/yadong.zhang/JustAuth/issues/IY2OH)
3. 解决Issue [#IY2FV](https://gitee.com/yadong.zhang/JustAuth/issues/IY2FV)
4. 修复部分注释、拼写错误
5. 解决Issue [#IY1QR](https://gitee.com/yadong.zhang/JustAuth/issues/IY1QR) 增加对Config属性的校验功能主要校验redirect uri的合法性
6. 合并[skqing](https://gitee.com/skqing)提交的[PR](https://gitee.com/yadong.zhang/JustAuth/pulls/2)
### 2019/06/06 ### 2019/06/06
1. 增加今日头条的授权登陆 1. 增加今日头条的授权登陆
2. 发布1.6.0-beta版本今日头条开发者暂时不能认证 所以无法做测试等测试通过后正式发布release版本 2. 发布1.6.0-beta版本今日头条开发者暂时不能认证 所以无法做测试等测试通过后正式发布release版本