diff --git a/README.md b/README.md index cde29716b7e25d1253aa70e454c0ff3ddced27d1..a410b1140a8d23bdbacf3fed61b8f3c433fd3768 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
@@ -76,7 +76,7 @@ JustAuth,如你所见,它仅仅是一个**第三方授权登录**的**工具- * 1.8.0版本新增参数 - */ - private String state; - /** * Stack Overflow Key *
diff --git a/src/main/java/me/zhyd/oauth/config/AuthSource.java b/src/main/java/me/zhyd/oauth/config/AuthSource.java index 1ea6704427bfa47502506e8c6cf626559ec6b1e9..a9a0a617ab392c430d309be62da857986c27851d 100644 --- a/src/main/java/me/zhyd/oauth/config/AuthSource.java +++ b/src/main/java/me/zhyd/oauth/config/AuthSource.java @@ -7,7 +7,6 @@ import me.zhyd.oauth.model.AuthResponseStatus; * 各api需要的url, 用枚举类分平台类型管理 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.0 */ public enum AuthSource { diff --git a/src/main/java/me/zhyd/oauth/enums/AuthToutiaoErrorCode.java b/src/main/java/me/zhyd/oauth/enums/AuthToutiaoErrorCode.java index 11007b257ca620fdbbbf507ea728c72688ec8cb4..18df6eeb8833303faba215b1fbddbf25f35ec733 100644 --- a/src/main/java/me/zhyd/oauth/enums/AuthToutiaoErrorCode.java +++ b/src/main/java/me/zhyd/oauth/enums/AuthToutiaoErrorCode.java @@ -7,7 +7,6 @@ import lombok.Getter; * 今日头条授权登录时的异常状态码 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ @Getter diff --git a/src/main/java/me/zhyd/oauth/enums/AuthUserGender.java b/src/main/java/me/zhyd/oauth/enums/AuthUserGender.java index 3e39e3df57251c2355b8ef936be475c9ea894589..4a4d4021789341b5b212c3fb7f9175ec6d6664f5 100644 --- a/src/main/java/me/zhyd/oauth/enums/AuthUserGender.java +++ b/src/main/java/me/zhyd/oauth/enums/AuthUserGender.java @@ -9,7 +9,6 @@ import java.util.Arrays; * 用户性别 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ @Getter diff --git a/src/main/java/me/zhyd/oauth/exception/AuthException.java b/src/main/java/me/zhyd/oauth/exception/AuthException.java index f4f7473c8790f0d8daa240ed46ff8b6ce71eae3e..c64b0f865e4053ed0c5ad31eb25375b1512c4c83 100644 --- a/src/main/java/me/zhyd/oauth/exception/AuthException.java +++ b/src/main/java/me/zhyd/oauth/exception/AuthException.java @@ -4,7 +4,6 @@ import me.zhyd.oauth.model.AuthResponseStatus; /** * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ public class AuthException extends RuntimeException { diff --git a/src/main/java/me/zhyd/oauth/model/AuthCallback.java b/src/main/java/me/zhyd/oauth/model/AuthCallback.java index fbc08edf54cba9c32d205464711cdbefba05281d..4a6fbeefc416a5feaa4a1b8a9aaa642a229b1768 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthCallback.java +++ b/src/main/java/me/zhyd/oauth/model/AuthCallback.java @@ -2,13 +2,13 @@ package me.zhyd.oauth.model; import lombok.Getter; import lombok.Setter; +import me.zhyd.oauth.cache.AuthStateCache; /** * 授权回调时的参数类 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.8.0 */ @Getter @Setter @@ -28,4 +28,14 @@ public class AuthCallback { * 访问AuthorizeUrl后回调时带的参数state,用于和请求AuthorizeUrl前的state比较,防止CSRF攻击 */ private String state; + + /** + * 内置的检验state合法性的方法 + * + * @return true: state正常;false:state不正常,可能授权时间过长导致state失效 + * @since 1.9.3 + */ + public boolean checkState() { + return AuthStateCache.containsKey(this.state); + } } diff --git a/src/main/java/me/zhyd/oauth/model/AuthResponse.java b/src/main/java/me/zhyd/oauth/model/AuthResponse.java index 484a743683373cf1a6f3ee4c394444826ec47891..3d682d5cff0c5d4430ddbcb1375e88246d96ff67 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthResponse.java +++ b/src/main/java/me/zhyd/oauth/model/AuthResponse.java @@ -8,7 +8,6 @@ import lombok.Setter; * JustAuth统一授权响应类 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ @Getter diff --git a/src/main/java/me/zhyd/oauth/model/AuthResponseStatus.java b/src/main/java/me/zhyd/oauth/model/AuthResponseStatus.java index 21ca6f63da2664b0eddb8b3cd32df3bcb803fb64..28247f9fda13728c122cdecdb6e82c48a9bcac72 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthResponseStatus.java +++ b/src/main/java/me/zhyd/oauth/model/AuthResponseStatus.java @@ -5,7 +5,6 @@ import lombok.Getter; /** * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ @Getter diff --git a/src/main/java/me/zhyd/oauth/model/AuthToken.java b/src/main/java/me/zhyd/oauth/model/AuthToken.java index 472d3d667a8f7ac3f1d856872b1e85659826a294..805a196c3c93b2149c07c5c44265e3d998fedea7 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthToken.java +++ b/src/main/java/me/zhyd/oauth/model/AuthToken.java @@ -9,7 +9,6 @@ import lombok.Setter; * 授权所需的token * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ @Getter diff --git a/src/main/java/me/zhyd/oauth/model/AuthUser.java b/src/main/java/me/zhyd/oauth/model/AuthUser.java index ad641299ad3956080064c8def7ca00b9e7f2bec5..d98e7272a1560add3a7a4ffd28c96e2c1714d537 100644 --- a/src/main/java/me/zhyd/oauth/model/AuthUser.java +++ b/src/main/java/me/zhyd/oauth/model/AuthUser.java @@ -10,7 +10,6 @@ import me.zhyd.oauth.enums.AuthUserGender; * 授权成功后的用户信息,根据授权平台的不同,获取的数据完整性也不同 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ @Getter @@ -19,6 +18,8 @@ import me.zhyd.oauth.enums.AuthUserGender; public class AuthUser { /** * 用户第三方系统的唯一id。在调用方集成改组件时,可以用uuid + source唯一确定一个用户 + * + * @since 1.3.3 */ private String uuid; /** diff --git a/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java b/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java index 07ce7da703a57a1aa77c681990c609d1c8a6dc28..5f8fbbf1a657bfd14d9ee5dad60f514e523f67dd 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java @@ -21,8 +21,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * 支付宝登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.1 */ public class AuthAlipayRequest extends AuthDefaultRequest { @@ -86,17 +85,19 @@ public class AuthAlipayRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("app_id", config.getClientId()) .queryParam("scope", "auth_user") .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } } diff --git a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java index 5ce2149a1ebdd3c4f4fa4314e8fbdf12f203f1cb..43796fe3be23235c52547ec4b6ee1a192f957109 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java @@ -15,8 +15,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * 百度账号登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ public class AuthBaiduRequest extends AuthDefaultRequest { @@ -79,18 +78,20 @@ public class AuthBaiduRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) .queryParam("display", "popup") - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java index 98e45bfdbec639cdce1631408c0b5c3cf4ff35ac..0ff52416e0c5906d1a3d13c6b715afa3b7f477de 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java @@ -4,19 +4,18 @@ import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSONObject; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; +import me.zhyd.oauth.enums.AuthUserGender; import me.zhyd.oauth.exception.AuthException; import me.zhyd.oauth.model.AuthCallback; import me.zhyd.oauth.model.AuthToken; import me.zhyd.oauth.model.AuthUser; -import me.zhyd.oauth.enums.AuthUserGender; import me.zhyd.oauth.utils.UrlBuilder; /** * Cooding登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ public class AuthCodingRequest extends AuthDefaultRequest { @@ -71,18 +70,20 @@ public class AuthCodingRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) .queryParam("scope", "user") - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } } diff --git a/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java b/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java index 3a72d3701643900d9dd727d790aefff508186ab7..a6c3776fadc19746b3989a4d39597e4bb8bcabc7 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthCsdnRequest.java @@ -14,8 +14,7 @@ import me.zhyd.oauth.model.AuthUser; * CSDN登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ @Deprecated public class AuthCsdnRequest extends AuthDefaultRequest { diff --git a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java index 1774a159d1a3b2f439878650c2386d1a0cce7ec9..354e3c5270344e8fab3b55c027c6deef95369f69 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java @@ -2,8 +2,8 @@ package me.zhyd.oauth.request; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; -import lombok.Data; import lombok.extern.slf4j.Slf4j; +import me.zhyd.oauth.cache.AuthStateCache; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; import me.zhyd.oauth.exception.AuthException; @@ -11,14 +11,14 @@ import me.zhyd.oauth.model.*; import me.zhyd.oauth.utils.AuthChecker; import me.zhyd.oauth.utils.StringUtils; import me.zhyd.oauth.utils.UrlBuilder; +import me.zhyd.oauth.utils.UuidUtils; /** * 默认的request处理类 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @author yangkai.shen (https://xkcoding.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ @Slf4j public abstract class AuthDefaultRequest implements AuthRequest { @@ -43,7 +43,6 @@ public abstract class AuthDefaultRequest implements AuthRequest { public AuthResponse login(AuthCallback authCallback) { try { AuthChecker.checkCode(source == AuthSource.ALIPAY ? authCallback.getAuth_code() : authCallback.getCode()); - AuthChecker.checkState(authCallback.getState(), config.getState()); AuthToken authToken = this.getAccessToken(authCallback); AuthUser user = this.getUserInfo(authToken); @@ -63,17 +62,34 @@ public abstract class AuthDefaultRequest implements AuthRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回授权url,可自行跳转页面 + *
+ * 不建议使用该方式获取授权地址,不带{@code state}的授权地址,容易受到csrf攻击。 + * 建议使用{@link AuthDefaultRequest#authorize(String)}方法生成授权地址,在回调方法中对{@code state}进行校验 * * @return 返回授权地址 + * @see AuthDefaultRequest#authorize(String) */ + @Deprecated @Override public String authorize() { + return this.authorize(null); + } + + /** + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} + * + * @param state state 验证授权流程的参数,可以防止csrf + * @return 返回授权地址 + * @since 1.9.3 + */ + @Override + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } @@ -130,13 +146,18 @@ public abstract class AuthDefaultRequest implements AuthRequest { } /** - * 获取state,如果为空, 则默认去当前日期的时间戳 + * 获取state,如果为空, 则默认取当前日期的时间戳 * * @param state 原始的state * @return 返回不为null的state */ protected String getRealState(String state) { - return StringUtils.isEmpty(state) ? String.valueOf(System.currentTimeMillis()) : state; + if (StringUtils.isEmpty(state)) { + state = UuidUtils.getUUID(); + } + // 缓存state + AuthStateCache.cache(state, state); + return state; } /** @@ -165,6 +186,7 @@ public abstract class AuthDefaultRequest implements AuthRequest { * @param authToken token封装 * @return HttpResponse */ + @Deprecated protected HttpResponse doPostUserInfo(AuthToken authToken) { return HttpRequest.post(userInfoUrl(authToken)).execute(); } @@ -184,7 +206,9 @@ public abstract class AuthDefaultRequest implements AuthRequest { * * @param authToken token封装 * @return HttpResponse + * @since */ + @Deprecated protected HttpResponse doPostRevoke(AuthToken authToken) { return HttpRequest.post(revokeUrl(authToken)).execute(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java index ce0f52fdde8ef4be657b9cd660edb7c425ea4ab8..b01eea5396f4a5943094959986516ee2a8971299 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java @@ -18,8 +18,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * 钉钉登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ public class AuthDingTalkRequest extends AuthDefaultRequest { @@ -58,18 +57,20 @@ public class AuthDingTalkRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("appid", config.getClientId()) .queryParam("scope", "snsapi_login") .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java index a68f232291330759c870c35570926f7bbdb517f1..cdab6aeac58a68356d792f50c99f817862717eaa 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java @@ -15,8 +15,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * 抖音登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.4.0 */ public class AuthDouyinRequest extends AuthDefaultRequest { @@ -89,18 +88,20 @@ public class AuthDouyinRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_key", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) .queryParam("scope", "user_info") + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java b/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java index 6d7cc2bab621106c0d703561791df855f9d2b241..96e0463cadfc222319bf796e63447e21ec486f33 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthFacebookRequest.java @@ -15,8 +15,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * Facebook登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.3.0 */ public class AuthFacebookRequest extends AuthDefaultRequest { diff --git a/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java b/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java index e32c1243e3107de906cd4e6e33221ea03d35667c..819e96c13068d4577b175716038099ce0ee15656 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGiteeRequest.java @@ -14,8 +14,7 @@ import me.zhyd.oauth.model.AuthUser; * Gitee登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ public class AuthGiteeRequest extends AuthDefaultRequest { diff --git a/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java b/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java index f71378ced50992fc05c9ccba06b15ccaed3c5035..00d98798512f13286238175731d4f6b1673598a6 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java @@ -17,8 +17,7 @@ import java.util.Map; * Github登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ public class AuthGithubRequest extends AuthDefaultRequest { @@ -63,12 +62,4 @@ public class AuthGithubRequest extends AuthDefaultRequest { .build(); } - /** - * 检查响应内容是否正确 - * - * @param object 请求响应内容 - */ - private void checkResponse(JSONObject object) { - - } } diff --git a/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java b/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java index 61b4f7fba2c0bf88139e33ccf5a38e86c2b9d281..8af2c415e020f86cb94a52d760f9327add044e7a 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java @@ -16,8 +16,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * Google登录 * * @author yangkai.shen (https://xkcoding.com) - * @version 1.3 - * @since 1.3 + * @since 1.3.0 */ public class AuthGoogleRequest extends AuthDefaultRequest { @@ -61,19 +60,20 @@ public class AuthGoogleRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 - * https://openidconnect.googleapis.com/v1/userinfo + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("scope", "openid%20email%20profile") .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java b/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java index e22a7417c0360f7ecdae406a4ba3206b89bd4612..adbb7e67078302f2c7544df822be5ddff387b2bd 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java @@ -18,8 +18,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * 领英登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.4.0 */ public class AuthLinkedinRequest extends AuthDefaultRequest { @@ -182,18 +181,20 @@ public class AuthLinkedinRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) .queryParam("scope", "r_liteprofile%20r_emailaddress%20w_member_social") + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java b/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java index 0ac9e00882d8a718cafc85e06e6caebf438b6b42..3b241e91c96ea11bb98d5c3d4ca22a23bfdb3a55 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java @@ -18,8 +18,7 @@ import java.text.MessageFormat; * 小米登录 * * @author yangkai.shen (https://xkcoding.com) - * @version 1.5 - * @since 1.5 + * @since 1.5.0 */ @Slf4j public class AuthMiRequest extends AuthDefaultRequest { @@ -109,19 +108,21 @@ public class AuthMiRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) .queryParam("scope", "user/profile%20user/openIdV2%20user/phoneAndEmail") .queryParam("skip_confirm", "false") + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java b/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java index addd187ede4c37328f6e7896b8b0ccb879abc795..55227afb2e31ba53c6a89eded8bcc557f50298b2 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java @@ -16,8 +16,7 @@ import static me.zhyd.oauth.utils.GlobalAuthUtil.parseQueryToMap; * 微软登录 * * @author yangkai.shen (https://xkcoding.com) - * @version 1.5 - * @since 1.5 + * @since 1.5.0 */ public class AuthMicrosoftRequest extends AuthDefaultRequest { public AuthMicrosoftRequest(AuthConfig config) { @@ -102,19 +101,21 @@ public class AuthMicrosoftRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 + * @since 1.9.3 */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) .queryParam("response_mode", "query") .queryParam("scope", "offline_access%20user.read%20mail.read") - .queryParam("state", getRealState(config.getState())) + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java b/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java index 58cc74367bb3dc819e3cd2639387a4ff1115e19a..c67819dcdbac44a5aa621f29d5b61d542cf5a31f 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthOschinaRequest.java @@ -15,8 +15,7 @@ import me.zhyd.oauth.utils.UrlBuilder; * oschina登录 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 - * @since 1.8 + * @since 1.0.0 */ public class AuthOschinaRequest extends AuthDefaultRequest { @@ -59,7 +58,7 @@ public class AuthOschinaRequest extends AuthDefaultRequest { /** * 返回获取accessToken的url * - * @param code + * @param code 授权回调时带回的授权码 * @return 返回获取accessToken的url */ @Override diff --git a/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java b/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java index a8f5c3835e3348196ef8ee3b8fe4d69bf2f08545..31151d51e07ee37807f41b6e7b8ece2070762484 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java @@ -19,8 +19,7 @@ import static me.zhyd.oauth.config.AuthSource.PINTEREST; * Pinterest登录 * * @author hongwei.peng (pengisgood(at)gmail(dot)com) - * @version 1.9.0 - * @since 1.8 + * @since 1.9.0 */ public class AuthPinterestRequest extends AuthDefaultRequest { @@ -69,14 +68,21 @@ public class AuthPinterestRequest extends AuthDefaultRequest { return jsonObject.getJSONObject("60x60").getString("url"); } + /** + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} + * + * @param state state 验证授权流程的参数,可以防止csrf + * @return 返回授权地址 + * @since 1.9.3 + */ @Override - public String authorize() { + public String authorize(String state) { return UrlBuilder.fromBaseUrl(source.authorize()) .queryParam("response_type", "code") .queryParam("client_id", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) - .queryParam("state", getRealState(config.getState())) .queryParam("scope", "read_public") + .queryParam("state", getRealState(state)) .build(); } diff --git a/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java b/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java index 1b8d6f9182891923b4cef3c2111d1fb18c3b4a37..274ccc24f405e37c04fe78ad4a62b9c768a4e0c2 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthQqRequest.java @@ -20,8 +20,7 @@ import java.util.Map; * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) * @author yangkai.shen (https://xkcoding.com) - * @version 1.0 - * @since 1.8 + * @since 1.1.0 */ public class AuthQqRequest extends AuthDefaultRequest { public AuthQqRequest(AuthConfig config) { @@ -69,6 +68,13 @@ public class AuthQqRequest extends AuthDefaultRequest { .build(); } + /** + * 获取QQ用户的OpenId,支持自定义是否启用查询unionid的功能,如果启用查询unionid的功能, + * 那就需要调用者先通过邮件申请unionid功能,参考链接 {@see http://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D} + * + * @param authToken 通过{@link AuthQqRequest#getAccessToken(AuthCallback)}获取到的{@code authToken} + * @return openId + */ private String getOpenId(AuthToken authToken) { HttpResponse response = HttpRequest.get(UrlBuilder.fromBaseUrl("https://graph.qq.com/oauth2.0/me") .queryParam("access_token", authToken.getAccessToken()) diff --git a/src/main/java/me/zhyd/oauth/request/AuthRenrenRequest.java b/src/main/java/me/zhyd/oauth/request/AuthRenrenRequest.java index 6888764dc40b2737ce31cfce93819562b3509a54..4b1186fd9114d2e0575b7ed4ebb4047f11762221 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthRenrenRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthRenrenRequest.java @@ -19,8 +19,7 @@ import static me.zhyd.oauth.model.AuthResponseStatus.SUCCESS; * 人人登录 * * @author hongwei.peng (pengisgood(at)gmail(dot)com) - * @version 1.9.0 - * @since 1.8 + * @since 1.9.0 */ public class AuthRenrenRequest extends AuthDefaultRequest { diff --git a/src/main/java/me/zhyd/oauth/request/AuthRequest.java b/src/main/java/me/zhyd/oauth/request/AuthRequest.java index d06913ccbbd466d9ed8b19e73200d285bdc4602b..6ceca1ee70b34f95e3d12ccca19b243f5a79c7b6 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthRequest.java @@ -8,20 +8,33 @@ import me.zhyd.oauth.model.AuthToken; /** * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 * @since 1.8 */ public interface AuthRequest { /** - * 返回认证url,可自行跳转页面 + * 返回授权url,可自行跳转页面 + *
+ * 不建议使用该方式获取授权地址,不带{@code state}的授权地址,容易受到csrf攻击。
+ * 建议使用{@link AuthDefaultRequest#authorize(String)}方法生成授权地址,在回调方法中对{@code state}进行校验
*
* @return 返回授权地址
*/
+ @Deprecated
default String authorize() {
throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
}
+ /**
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
+ *
+ * @param state state 验证授权流程的参数,可以防止csrf
+ * @return 返回授权地址
+ */
+ default String authorize(String state) {
+ throw new AuthException(AuthResponseStatus.NOT_IMPLEMENTED);
+ }
+
/**
* 第三方登录
*
diff --git a/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java b/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java
index c23439e75a48e6b4cbfb1bb9ba7c6b5b9121065a..ab484533392102cd1060adefedbf982e361b5cd3 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java
@@ -18,8 +18,7 @@ import static me.zhyd.oauth.utils.GlobalAuthUtil.parseQueryToMap;
* Stack Overflow登录
*
* @author hongwei.peng (pengisgood(at)gmail(dot)com)
- * @version 1.9.0
- * @since 1.8
+ * @since 1.9.0
*/
public class AuthStackOverflowRequest extends AuthDefaultRequest {
@@ -67,14 +66,21 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest {
.build();
}
+ /**
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
+ *
+ * @param state state 验证授权流程的参数,可以防止csrf
+ * @return 返回授权地址
+ * @since 1.9.3
+ */
@Override
- public String authorize() {
+ public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
- .queryParam("state", getRealState(config.getState()))
.queryParam("scope", "read_inbox")
+ .queryParam("state", getRealState(state))
.build();
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java b/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java
index 7a3b522eadbbbddabf848b03a66db274564a7a82..3fcdfdfe490e5b7fa556fe10ebc9ca90a79c5458 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthTaobaoRequest.java
@@ -4,11 +4,11 @@ import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthSource;
+import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
-import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.utils.GlobalAuthUtil;
import me.zhyd.oauth.utils.UrlBuilder;
@@ -16,8 +16,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
* 淘宝登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
+ * @since 1.1.0
*/
public class AuthTaobaoRequest extends AuthDefaultRequest {
@@ -55,18 +54,20 @@ public class AuthTaobaoRequest extends AuthDefaultRequest {
}
/**
- * 返回认证url,可自行跳转页面
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
+ * @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
+ * @since 1.9.3
*/
@Override
- public String authorize() {
+ public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
- .queryParam("state", getRealState(config.getState()))
.queryParam("view", "web")
+ .queryParam("state", getRealState(state))
.build();
}
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthTeambitionRequest.java b/src/main/java/me/zhyd/oauth/request/AuthTeambitionRequest.java
index d8e79f6068ef28d0e6f1d76e07638fa98aa5e5ce..50c1b7f35621eecfc74574d64afe4e9e27eca1d2 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthTeambitionRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthTeambitionRequest.java
@@ -13,8 +13,7 @@ import me.zhyd.oauth.model.*;
* Teambition授权登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
+ * @since 1.9.0
*/
public class AuthTeambitionRequest extends AuthDefaultRequest {
diff --git a/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java b/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java
index 7aaa77dc1d497812d4543508339a7abd5eac9519..7401df8d13c8eb9e07642eb752e8eb31ae35019b 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java
@@ -15,8 +15,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
* 腾讯云登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
+ * @since 1.0.0
*/
public class AuthTencentCloudRequest extends AuthDefaultRequest {
@@ -71,18 +70,20 @@ public class AuthTencentCloudRequest extends AuthDefaultRequest {
}
/**
- * 返回认证url,可自行跳转页面
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
+ * @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
+ * @since 1.9.3
*/
@Override
- public String authorize() {
+ public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("client_id", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("scope", "user")
- .queryParam("state", getRealState(config.getState()))
+ .queryParam("state", getRealState(state))
.build();
}
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java b/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java
index 2a1c9790f0f85e7329bfbfc949f1449dff05a0cf..89926f360b7e54d73a80314049c38f1411632a0d 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java
@@ -16,8 +16,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
* 今日头条登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.5
- * @since 1.5
+ * @since 1.6.0-beta
*/
public class AuthToutiaoRequest extends AuthDefaultRequest {
@@ -65,19 +64,21 @@ public class AuthToutiaoRequest extends AuthDefaultRequest {
}
/**
- * 返回认证url,可自行跳转页面
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
+ * @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
+ * @since 1.9.3
*/
@Override
- public String authorize() {
+ public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("client_key", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
- .queryParam("state", getRealState(config.getState()))
.queryParam("auth_only", 1)
.queryParam("display", 0)
+ .queryParam("state", getRealState(state))
.build();
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java b/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java
index dbc029a7f37a8a4f19adb9571077ce917a0a3d97..cf87013c457376fc7d48008c319cb3e9f0bb224b 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java
@@ -14,8 +14,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
* 微信登录
*
* @author yangkai.shen (https://xkcoding.com)
- * @version 1.0
- * @since 1.8
+ * @since 1.1.0
*/
public class AuthWeChatRequest extends AuthDefaultRequest {
public AuthWeChatRequest(AuthConfig config) {
@@ -100,18 +99,20 @@ public class AuthWeChatRequest extends AuthDefaultRequest {
}
/**
- * 返回认证url,可自行跳转页面
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
*
+ * @param state state 验证授权流程的参数,可以防止csrf
* @return 返回授权地址
+ * @since 1.9.3
*/
@Override
- public String authorize() {
+ public String authorize(String state) {
return UrlBuilder.fromBaseUrl(source.authorize())
.queryParam("response_type", "code")
.queryParam("appid", config.getClientId())
.queryParam("redirect_uri", config.getRedirectUri())
.queryParam("scope", "snsapi_login")
- .queryParam("state", getRealState(config.getState()).concat("#wechat_redirect"))
+ .queryParam("state", getRealState(state))
.build();
}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java b/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java
index cf1df17d290a0902397e729209149f6ff97f7e4b..9f226d847876b189b2a9e79a4ed432c6024a7282 100644
--- a/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java
+++ b/src/main/java/me/zhyd/oauth/request/AuthWeiboRequest.java
@@ -19,8 +19,7 @@ import me.zhyd.oauth.utils.UrlBuilder;
* 微博登录
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
+ * @since 1.0.0
*/
public class AuthWeiboRequest extends AuthDefaultRequest {
@@ -51,7 +50,7 @@ public class AuthWeiboRequest extends AuthDefaultRequest {
String oauthParam = String.format("uid=%s&access_token=%s", uid, accessToken);
HttpResponse response = HttpRequest.get(userInfoUrl(authToken))
.header("Authorization", "OAuth2 " + oauthParam)
- .header("API-RemoteIP", IpUtils.getIp())
+ .header("API-RemoteIP", IpUtils.getLocalIp())
.execute();
String userInfo = response.body();
JSONObject object = JSONObject.parseObject(userInfo);
diff --git a/src/main/java/me/zhyd/oauth/utils/AuthChecker.java b/src/main/java/me/zhyd/oauth/utils/AuthChecker.java
index 33b59c3556bb3686a7644e0f24746d8462517ce6..3cbd6adc0d71886fa11f35998f6f95e3dd7b5b13 100644
--- a/src/main/java/me/zhyd/oauth/utils/AuthChecker.java
+++ b/src/main/java/me/zhyd/oauth/utils/AuthChecker.java
@@ -9,8 +9,7 @@ import me.zhyd.oauth.model.AuthResponseStatus;
* 授权配置类的校验器
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
+ * @since 1.6.1-beta
*/
public class AuthChecker {
@@ -20,6 +19,7 @@ public class AuthChecker {
* @param config config
* @param source source
* @return true or false
+ * @since 1.6.1-beta
*/
public static boolean isSupportedAuth(AuthConfig config, AuthSource source) {
boolean isSupported = StringUtils.isNotEmpty(config.getClientId()) && StringUtils.isNotEmpty(config.getClientSecret()) && StringUtils.isNotEmpty(config.getRedirectUri());
@@ -37,6 +37,7 @@ public class AuthChecker {
*
* @param config config
* @param source source
+ * @since 1.6.1-beta
*/
public static void checkConfig(AuthConfig config, AuthSource source) {
String redirectUri = config.getRedirectUri();
@@ -57,31 +58,11 @@ public class AuthChecker {
* 校验回调传回的code
*
* @param code 回调时传回的code
+ * @since 1.8.0
*/
public static void checkCode(String code) {
if (StringUtils.isEmpty(code)) {
throw new AuthException(AuthResponseStatus.ILLEGAL_CODE);
}
}
-
- /**
- * 校验state的合法性防止被CSRF
- *
- * @param newState 新的state,一般为回调时传回的state(可能被篡改)
- * @param originalState 原始的state,发起授权时向第三方平台传递的state
- */
- public static void checkState(String newState, String originalState) {
- // 如果原始state为空,表示当前平台未使用state
- if (StringUtils.isEmpty(originalState)) {
- return;
- }
- // 如果授权之前使用了state,但是回调时未返回state,则表示当前请求为非法的请求,可能正在被CSRF攻击
- if (StringUtils.isEmpty(newState)) {
- throw new AuthException(AuthResponseStatus.ILLEGAL_REQUEST);
- }
- // 如果授权前后的state不一致,则表示当前请求为非法的请求,新的state可能为伪造
- if (!newState.equals(originalState)) {
- throw new AuthException(AuthResponseStatus.ILLEGAL_REQUEST);
- }
- }
}
diff --git a/src/main/java/me/zhyd/oauth/utils/AuthState.java b/src/main/java/me/zhyd/oauth/utils/AuthState.java
deleted file mode 100644
index 1ca1b70f3915ffb346159e49109065e0239cbdc4..0000000000000000000000000000000000000000
--- a/src/main/java/me/zhyd/oauth/utils/AuthState.java
+++ /dev/null
@@ -1,230 +0,0 @@
-package me.zhyd.oauth.utils;
-
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.util.RandomUtil;
-import com.alibaba.fastjson.JSON;
-import lombok.extern.slf4j.Slf4j;
-import me.zhyd.oauth.config.AuthSource;
-import me.zhyd.oauth.exception.AuthException;
-import me.zhyd.oauth.model.AuthResponseStatus;
-
-import java.nio.charset.Charset;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * state工具,负责创建、获取和删除state
- *
- * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
- */
-@Slf4j
-public class AuthState {
-
- /**
- * 空字符串
- */
- private static final String EMPTY_STR = "";
-
- /**
- * state存储器
- */
- private static ConcurrentHashMap
+ * 关于mica uuid生成方式的压测结果,可以参考:https://github.com/lets-mica/mica-jmh/wiki/uuid
+ *
+ * @return UUID
+ */
+ public static String getUUID() {
+ ThreadLocalRandom random = ThreadLocalRandom.current();
+ long lsb = random.nextLong();
+ long msb = random.nextLong();
+ byte[] buf = new byte[32];
+ formatUnsignedLong(lsb, buf, 20, 12);
+ formatUnsignedLong(lsb >>> 48, buf, 16, 4);
+ formatUnsignedLong(msb, buf, 12, 4);
+ formatUnsignedLong(msb >>> 16, buf, 8, 4);
+ formatUnsignedLong(msb >>> 32, buf, 0, 8);
+ return new String(buf, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * copy from mica:https://github.com/lets-mica/mica/blob/master/mica-core/src/main/java/net/dreamlu/mica/core/utils/StringUtil.java#L348
+ */
+ private static void formatUnsignedLong(long val, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << 4;
+ int mask = radix - 1;
+ do {
+ buf[--charPos] = DIGITS[((int) val) & mask];
+ val >>>= 4;
+ } while (charPos > offset);
+ }
+}
diff --git a/src/test/java/me/zhyd/oauth/AuthRequestTest.java b/src/test/java/me/zhyd/oauth/AuthRequestTest.java
index a4c4a311b6b59defb484901180a1d1558136e401..9b50f536e624490b6cb5ad8814df2645a23b7a02 100644
--- a/src/test/java/me/zhyd/oauth/AuthRequestTest.java
+++ b/src/test/java/me/zhyd/oauth/AuthRequestTest.java
@@ -8,274 +8,292 @@ import org.junit.Test;
/**
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
- * @version 1.0
- * @since 1.8
*/
public class AuthRequestTest {
@Test
public void giteeTest() {
AuthRequest authRequest = new AuthGiteeRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void githubTest() {
AuthRequest authRequest = new AuthGithubRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void weiboTest() {
AuthRequest authRequest = new AuthWeiboRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void dingdingTest() {
AuthRequest authRequest = new AuthDingTalkRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void baiduTest() {
AuthRequest authRequest = new AuthBaiduRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void codingTest() {
AuthRequest authRequest = new AuthCodingRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void tencentCloudTest() {
AuthRequest authRequest = new AuthTencentCloudRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void oschinaTest() {
AuthRequest authRequest = new AuthOschinaRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
authRequest.login(new AuthCallback());
}
@Test
public void alipayTest() {
AuthRequest authRequest = new AuthAlipayRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .alipayPublicKey("publicKey")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .alipayPublicKey("publicKey")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void qqTest() {
AuthRequest authRequest = new AuthQqRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void wechatTest() {
AuthRequest authRequest = new AuthWeChatRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void taobaoTest() {
AuthRequest authRequest = new AuthTaobaoRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void googleTest() {
AuthRequest authRequest = new AuthGoogleRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void facebookTest() {
AuthRequest authRequest = new AuthFacebookRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void douyinTest() {
AuthRequest authRequest = new AuthDouyinRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void linkedinTest() {
AuthRequest authRequest = new AuthLinkedinRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void microsoftTest() {
AuthRequest authRequest = new AuthMicrosoftRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void miTest() {
AuthRequest authRequest = new AuthMiRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
@Test
public void toutiaoTest() {
AuthRequest authRequest = new AuthToutiaoRequest(AuthConfig.builder()
- .clientId("clientId")
- .clientSecret("clientSecret")
- .redirectUri("redirectUri")
- .state("state")
- .build());
+ .clientId("clientId")
+ .clientSecret("clientSecret")
+ .redirectUri("redirectUri")
+ .build());
// 返回授权页面,可自行跳转
- String url = authRequest.authorize();
+ authRequest.authorize("state");
// 授权登录后会返回code(auth_code(仅限支付宝))、state,1.8.0版本后,可以用AuthCallback类作为回调接口的入参
+ // 1.9.3版本后 如果需要验证state,可以在login之前调用{@see AuthCallback#checkState}方法校验state合法性
+ // 注:JustAuth默认保存state的时效为3分钟,3分钟内未使用则会自动清除过期的state
AuthResponse login = authRequest.login(new AuthCallback());
}
}
diff --git a/src/test/java/me/zhyd/oauth/cache/AuthStateCacheTest.java b/src/test/java/me/zhyd/oauth/cache/AuthStateCacheTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c6e1e04389e60473f97fea28924f0d587dd08e1
--- /dev/null
+++ b/src/test/java/me/zhyd/oauth/cache/AuthStateCacheTest.java
@@ -0,0 +1,32 @@
+package me.zhyd.oauth.cache;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+public class AuthStateCacheTest {
+
+ @Test
+ public void cache1() throws InterruptedException {
+ AuthStateCache.cache("key", "value");
+ Assert.assertEquals(AuthStateCache.get("key"), "value");
+
+ TimeUnit.MILLISECONDS.sleep(4);
+ Assert.assertEquals(AuthStateCache.get("key"), "value");
+ }
+
+ @Test
+ public void cache2() throws InterruptedException {
+ AuthStateCache.cache("key", "value", 10);
+ Assert.assertEquals(AuthStateCache.get("key"), "value");
+
+ // 没过期
+ TimeUnit.MILLISECONDS.sleep(5);
+ Assert.assertEquals(AuthStateCache.get("key"), "value");
+
+ // 过期
+ TimeUnit.MILLISECONDS.sleep(6);
+ Assert.assertNull(AuthStateCache.get("key"));
+ }
+}
diff --git a/src/test/java/me/zhyd/oauth/utils/AuthStateTest.java b/src/test/java/me/zhyd/oauth/utils/AuthStateTest.java
deleted file mode 100644
index d73489d27078c1881e0961b834a2cd640843106b..0000000000000000000000000000000000000000
--- a/src/test/java/me/zhyd/oauth/utils/AuthStateTest.java
+++ /dev/null
@@ -1,231 +0,0 @@
-package me.zhyd.oauth.utils;
-
-import cn.hutool.core.date.DatePattern;
-import cn.hutool.core.date.DateUtil;
-import me.zhyd.oauth.config.AuthConfig;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.*;
-
-public class AuthStateTest {
-
- /**
- * step1 生成state: 预期创建一个新的state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV9yM3ll
- *
- * step2 重复生成state: 预期从bucket中返回一个可用的state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV9yM3ll
- *
- * step3 获取state: 预期获取上面生成的state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV9yM3ll
- *
- * step4 删除state: 预期删除掉上面创建的state...
- *
- * step5 重新获取state: 预期返回null...
- * null
- */
- @Test
- public void usage() {
- String source = "github";
- System.out.println("\nstep1 生成state: 预期创建一个新的state...");
- String state = AuthState.create(source);
- System.out.println(state);
-
- System.out.println("\nstep2 重复生成state: 预期从bucket中返回一个可用的state...");
- String recreateState = AuthState.create(source);
- System.out.println(recreateState);
- Assert.assertEquals(state, recreateState);
-
- System.out.println("\nstep3 获取state: 预期获取上面生成的state...");
- String stateByBucket = AuthState.get(source);
- System.out.println(stateByBucket);
- Assert.assertEquals(state, stateByBucket);
-
- System.out.println("\nstep4 删除state: 预期删除掉上面创建的state...");
- AuthState.delete(source);
-
- System.out.println("\nstep5 重新获取state: 预期返回null...");
- String deletedState = AuthState.get(source);
- System.out.println(deletedState);
- Assert.assertNull(deletedState);
- }
-
- /**
- * 通过随机字符串生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV9wdnAy
- *
- * 通过传入自定义的字符串生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV/ov5nmmK/kuIDkuKrlrZfnrKbkuLI=
- *
- * 通过传入数字生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV8xMTE=
- *
- * 通过传入日期生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV8xNTQ2MzE1OTMyMDAw
- *
- * 通过传入map生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV97InVzZXJUb2tlbiI6Inh4eHh4IiwidXNlcklkIjoxfQ==
- *
- * 通过传入List生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV9bInh4eHgiLCJ4eHh4eHh4eCJd
- *
- * 通过传入实体类生成state...
- * Z2l0aHViXzE5Mi4xNjguMTkuMV97ImNsaWVudElkIjoieHh4eHgiLCJjbGllbnRTZWNyZXQiOiJ4eHh4eCIsInVuaW9uSWQiOmZhbHNlfQ==
- */
- @Test
- public void create() {
- String source = "github";
- System.out.println("\n通过随机字符串生成state...");
- String state = AuthState.create(source);
- System.out.println(state);
- AuthState.delete(source);
-
- System.out.println("\n通过传入自定义的字符串生成state...");
- String stringBody = "这是一个字符串";
- String stringState = AuthState.create(source, stringBody);
- System.out.println(stringState);
- AuthState.delete(source);
-
- System.out.println("\n通过传入数字生成state...");
- Integer numberBody = 111;
- String numberState = AuthState.create(source, numberBody);
- System.out.println(numberState);
- AuthState.delete(source);
-
- System.out.println("\n通过传入日期生成state...");
- Date dateBody = DateUtil.parse("2019-01-01 12:12:12", DatePattern.NORM_DATETIME_PATTERN);
- String dateState = AuthState.create(source, dateBody);
- System.out.println(dateState);
- AuthState.delete(source);
-
- System.out.println("\n通过传入map生成state...");
- Map