diff --git a/src/main/java/me/zhyd/oauth/config/AuthConfig.java b/src/main/java/me/zhyd/oauth/config/AuthConfig.java index 6e72e826dda11874f22900392e04418615296074..f0eb3494943aa7c8dde91d619facfc8af0c5c947 100644 --- a/src/main/java/me/zhyd/oauth/config/AuthConfig.java +++ b/src/main/java/me/zhyd/oauth/config/AuthConfig.java @@ -6,7 +6,7 @@ import lombok.*; * JustAuth配置类 * * @author yadong.zhang (yadong.zhang0415(a)gmail.com) - * @version 1.0 + * @version 1.9.3 * @since 1.8 */ @Getter @@ -45,13 +45,6 @@ public class AuthConfig { */ private boolean unionId; - /** - * 一个神奇的参数,最好使用随机的不可测的内容,可以用来防止CSRF攻击 - *

- * 1.8.0版本新增参数 - */ - private String state; - /** * Stack Overflow Key *

diff --git a/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java b/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java index 07ce7da703a57a1aa77c681990c609d1c8a6dc28..f0c6f90edace21a98845b4b02f6db119efcee65d 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthAlipayRequest.java @@ -86,17 +86,18 @@ public class AuthAlipayRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..11492b555943e3b4c57f9fe2bbc97c7ed58381e7 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthBaiduRequest.java @@ -79,18 +79,19 @@ public class AuthBaiduRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..ae28769917db8cb7fdf22194b345eb1167c87a6a 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthCodingRequest.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.UrlBuilder; /** @@ -71,18 +71,19 @@ public class AuthCodingRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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/AuthDefaultRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java index 1774a159d1a3b2f439878650c2386d1a0cce7ec9..7a8848ff4c2521e8f94ec69639a308264cb321ed 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDefaultRequest.java @@ -2,7 +2,6 @@ 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.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; @@ -43,7 +42,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); @@ -64,16 +62,31 @@ public abstract class AuthDefaultRequest implements AuthRequest { /** * 返回认证url,可自行跳转页面 + *

+ * 不建议使用该方式获取授权地址,不带{@code state}的授权地址,容易受到csrf攻击。 + * 建议使用{@link AuthDefaultRequest#authorize(String)}方法生成授权地址,在回调方法中对{@code state}进行校验 * * @return 返回授权地址 */ + @Deprecated @Override public String authorize() { + return this.authorize(null); + } + + /** + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} + * + * @param state state 验证授权流程的参数,可以防止csrf + * @return 返回授权地址 + */ + @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,7 +143,7 @@ public abstract class AuthDefaultRequest implements AuthRequest { } /** - * 获取state,如果为空, 则默认去当前日期的时间戳 + * 获取state,如果为空, 则默认取当前日期的时间戳 * * @param state 原始的state * @return 返回不为null的state diff --git a/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java b/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java index ce0f52fdde8ef4be657b9cd660edb7c425ea4ab8..ad29df0f8d35da8a3500fccbf7c929d430560d51 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDingTalkRequest.java @@ -58,18 +58,19 @@ public class AuthDingTalkRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..db9582c6096290e8b59f3e04ece71bfa2191758d 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthDouyinRequest.java @@ -89,18 +89,19 @@ public class AuthDouyinRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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/AuthGithubRequest.java b/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java index f71378ced50992fc05c9ccba06b15ccaed3c5035..fb4a64a3f072180c5fdaaff85d91c931fb9e8942 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGithubRequest.java @@ -63,12 +63,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..a3033a160fdfbe0dbfe29bcb1967c445359afafb 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthGoogleRequest.java @@ -61,19 +61,19 @@ public class AuthGoogleRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 - * https://openidconnect.googleapis.com/v1/userinfo + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..3deefb716eb3719af87ec4ff80e79cc405e668d4 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthLinkedinRequest.java @@ -182,18 +182,19 @@ public class AuthLinkedinRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..abdcb10b8c5d22d785f1dfd51d6daadafd313f6b 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthMiRequest.java @@ -109,19 +109,20 @@ public class AuthMiRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..4716c15e1f086e2aa9c6656b65111ae0772c7f0e 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthMicrosoftRequest.java @@ -102,19 +102,20 @@ public class AuthMicrosoftRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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/AuthPinterestRequest.java b/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java index a8f5c3835e3348196ef8ee3b8fe4d69bf2f08545..7c3f0001538c706559f2b1dcce71101a89e402b2 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthPinterestRequest.java @@ -69,14 +69,20 @@ public class AuthPinterestRequest extends AuthDefaultRequest { return jsonObject.getJSONObject("60x60").getString("url"); } + /** + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} + * + * @param state state 验证授权流程的参数,可以防止csrf + * @return 返回授权地址 + */ @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/AuthRequest.java b/src/main/java/me/zhyd/oauth/request/AuthRequest.java index d06913ccbbd466d9ed8b19e73200d285bdc4602b..7b838e75515dd188491f05a96a4b7f0e10121fdc 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthRequest.java @@ -18,10 +18,21 @@ public interface AuthRequest { * * @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..cf438c272d76fd07250050ae961d2604303467ba 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthStackOverflowRequest.java @@ -67,14 +67,20 @@ public class AuthStackOverflowRequest extends AuthDefaultRequest { .build(); } + /** + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} + * + * @param state state 验证授权流程的参数,可以防止csrf + * @return 返回授权地址 + */ @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..f350ccd693de15b1fa2b1e510ef89f5289a451ff 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; @@ -55,18 +55,19 @@ public class AuthTaobaoRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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/AuthTencentCloudRequest.java b/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java index 7aaa77dc1d497812d4543508339a7abd5eac9519..5930aeb072f41c5c9c3eff74765d8449d2209401 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthTencentCloudRequest.java @@ -71,18 +71,19 @@ public class AuthTencentCloudRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..ab73d3a62f0096be0554ce381202803826cc03aa 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthToutiaoRequest.java @@ -65,19 +65,20 @@ public class AuthToutiaoRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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..f22f35409bebde8d6fb19e3c0e8d66fbcbc664da 100644 --- a/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java +++ b/src/main/java/me/zhyd/oauth/request/AuthWeChatRequest.java @@ -100,18 +100,19 @@ public class AuthWeChatRequest extends AuthDefaultRequest { } /** - * 返回认证url,可自行跳转页面 + * 返回带{@code state}参数的认证url,授权回调时会带上这个{@code state} * + * @param state state 验证授权流程的参数,可以防止csrf * @return 返回授权地址 */ @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/utils/AuthChecker.java b/src/main/java/me/zhyd/oauth/utils/AuthChecker.java index 33b59c3556bb3686a7644e0f24746d8462517ce6..ddb70beeafc3c49101a80b7fef13b9ef2ebd8e43 100644 --- a/src/main/java/me/zhyd/oauth/utils/AuthChecker.java +++ b/src/main/java/me/zhyd/oauth/utils/AuthChecker.java @@ -63,25 +63,4 @@ public class AuthChecker { 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 stateBucket = new ConcurrentHashMap<>(); - - /** - * 生成随机的state - * - * @param source oauth平台 - * @return state - */ - public static String create(AuthSource source) { - return create(source.name()); - } - - /** - * 生成随机的state - * - * @param source oauth平台 - * @return state - */ - public static String create(String source) { - return create(source, RandomUtil.randomString(4)); - } - - /** - * 创建state - * - * @param source oauth平台 - * @param body 希望加密到state的消息体 - * @return state - */ - public static String create(AuthSource source, Object body) { - return create(source, JSON.toJSONString(body)); - } - - /** - * 创建state - * - * @param source oauth平台 - * @param body 希望加密到state的消息体 - * @return state - */ - public static String create(String source, Object body) { - return create(source, JSON.toJSONString(body)); - } - - /** - * 创建state - * - * @param source oauth平台 - * @param body 希望加密到state的消息体 - * @return state - */ - public static String create(AuthSource source, String body) { - return create(source.name(), body); - } - - /** - * 创建state - * - * @param source oauth平台 - * @param body 希望加密到state的消息体 - * @return state - */ - public static String create(String source, String body) { - String currentIp = getCurrentIp(); - String simpleKey = ((source + currentIp)); - String key = Base64.encode(simpleKey.getBytes(Charset.forName("UTF-8"))); - log.debug("Create the state: ip={}, platform={}, simpleKey={}, key={}, body={}", currentIp, source, simpleKey, key, body); - - if (stateBucket.containsKey(key)) { - log.debug("Get from bucket: {}", stateBucket.get(key)); - return stateBucket.get(key); - } - - String simpleState = source + "_" + currentIp + "_" + body; - String state = Base64.encode(simpleState.getBytes(Charset.forName("UTF-8"))); - log.debug("Create a new state: {}", state, simpleState); - stateBucket.put(key, state); - return state; - } - - /** - * 获取state - * - * @param source oauth平台 - * @return state - */ - public static String get(AuthSource source) { - return get(source.name()); - } - - /** - * 获取state - * - * @param source oauth平台 - * @return state - */ - public static String get(String source) { - String currentIp = getCurrentIp(); - String simpleKey = ((source + currentIp)); - String key = Base64.encode(simpleKey.getBytes(Charset.forName("UTF-8"))); - log.debug("Get state by the key[{}], current ip[{}]", key, currentIp); - return stateBucket.get(key); - } - - /** - * 获取state中保存的body内容 - * - * @param source oauth平台 - * @param state 加密后的state - * @param clazz body的实际类型 - * @param 需要转换的具体的class类型 - * @return state - */ - public static T getBody(AuthSource source, String state, Class clazz) { - return getBody(source.name(), state, clazz); - } - - /** - * 获取state中保存的body内容 - * - * @param source oauth平台 - * @param state 加密后的state - * @param clazz body的实际类型 - * @param 需要转换的具体的class类型 - * @return state - */ - public static T getBody(String source, String state, Class clazz) { - if (StringUtils.isEmpty(state) || null == clazz) { - return null; - } - log.debug("Get body from the state[{}] of the {} and convert it to {}", state, source, clazz.toString()); - String currentIp = getCurrentIp(); - String decodedState = Base64.decodeStr(state); - log.debug("The decoded state is [{}]", decodedState); - if (!decodedState.startsWith(source)) { - return null; - } - String noneSourceState = decodedState.substring(source.length() + 1); - if (!noneSourceState.startsWith(currentIp)) { - // ip不相同,可能为非法的请求 - throw new AuthException(AuthResponseStatus.ILLEGAL_REQUEST); - } - String body = noneSourceState.substring(currentIp.length() + 1); - log.debug("body is [{}]", body); - if (clazz == String.class) { - return (T) body; - } - if (clazz == Integer.class) { - return (T) Integer.valueOf(Integer.parseInt(body)); - } - if (clazz == Long.class) { - return (T) Long.valueOf(Long.parseLong(body)); - } - if (clazz == Short.class) { - return (T) Short.valueOf(Short.parseShort(body)); - } - if (clazz == Double.class) { - return (T) Double.valueOf(Double.parseDouble(body)); - } - if (clazz == Float.class) { - return (T) Float.valueOf(Float.parseFloat(body)); - } - if (clazz == Boolean.class) { - return (T) Boolean.valueOf(Boolean.parseBoolean(body)); - } - if (clazz == Byte.class) { - return (T) Byte.valueOf(Byte.parseByte(body)); - } - return JSON.parseObject(body, clazz); - } - - /** - * 登录成功后,清除state - * - * @param source oauth平台 - */ - public static void delete(String source) { - String currentIp = getCurrentIp(); - - String simpleKey = ((source + currentIp)); - String key = Base64.encode(simpleKey.getBytes(Charset.forName("UTF-8"))); - log.debug("Delete used state[{}] by the key[{}], current ip[{}]", stateBucket.get(key), key, currentIp); - stateBucket.remove(key); - } - - /** - * 登录成功后,清除state - * - * @param source oauth平台 - */ - public static void delete(AuthSource source) { - delete(source.name()); - } - - private static String getCurrentIp() { - String currentIp = IpUtils.getIp(); - return StringUtils.isEmpty(currentIp) ? EMPTY_STR : currentIp; - } -} diff --git a/src/test/java/me/zhyd/oauth/AuthRequestTest.java b/src/test/java/me/zhyd/oauth/AuthRequestTest.java index a4c4a311b6b59defb484901180a1d1558136e401..3ec2c5de0919fcb6149f0cc12efd00f787a3d5f6 100644 --- a/src/test/java/me/zhyd/oauth/AuthRequestTest.java +++ b/src/test/java/me/zhyd/oauth/AuthRequestTest.java @@ -16,13 +16,12 @@ 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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -30,13 +29,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -44,12 +42,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -57,13 +55,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -71,13 +68,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -85,13 +81,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -99,13 +94,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -113,13 +107,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 authRequest.login(new AuthCallback()); } @@ -127,14 +120,13 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -142,13 +134,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -156,13 +147,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -170,13 +160,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -184,13 +173,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -198,13 +186,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -212,13 +199,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -226,13 +212,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -240,13 +225,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -254,13 +238,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } @@ -268,13 +251,12 @@ public class AuthRequestTest { @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类作为回调接口的入参 AuthResponse login = authRequest.login(new AuthCallback()); } 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 mapBody = new HashMap<>(); - mapBody.put("userId", 1); - mapBody.put("userToken", "xxxxx"); - String mapState = AuthState.create(source, mapBody); - System.out.println(mapState); - AuthState.delete(source); - - System.out.println("\n通过传入List生成state..."); - List listBody = new ArrayList<>(); - listBody.add("xxxx"); - listBody.add("xxxxxxxx"); - String listState = AuthState.create(source, listBody); - System.out.println(listState); - AuthState.delete(source); - - System.out.println("\n通过传入实体类生成state..."); - AuthConfig entityBody = AuthConfig.builder() - .clientId("xxxxx") - .clientSecret("xxxxx") - .build(); - String entityState = AuthState.create(source, entityBody); - System.out.println(entityState); - AuthState.delete(source); - } - - /** - * 通过随机字符串生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV9kaWNn - * dicg - * - * 通过传入自定义的字符串生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV/ov5nmmK/kuIDkuKrlrZfnrKbkuLI= - * 这是一个字符串 - * - * 通过传入数字生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV8xMTE= - * 111 - * - * 通过传入日期生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV8xNTQ2MzE1OTMyMDAw - * Tue Jan 01 12:12:12 CST 2019 - * - * 通过传入map生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV97InVzZXJUb2tlbiI6Inh4eHh4IiwidXNlcklkIjoxfQ== - * {userToken=xxxxx, userId=1} - * - * 通过传入List生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV9bInh4eHgiLCJ4eHh4eHh4eCJd - * [xxxx, xxxxxxxx] - * - * 通过传入实体类生成state... - * Z2l0aHViXzE5Mi4xNjguMTkuMV97ImNsaWVudElkIjoieHh4eHgiLCJjbGllbnRTZWNyZXQiOiJ4eHh4eCIsInVuaW9uSWQiOmZhbHNlfQ== - * me.zhyd.oauth.config.AuthConfig@725bef66 - */ - @Test - public void getBody() { - String source = "github"; - System.out.println("\n通过随机字符串生成state..."); - String state = AuthState.create(source); - System.out.println(state); - String body = AuthState.getBody(source, state, String.class); - System.out.println(body); - AuthState.delete(source); - - System.out.println("\n通过传入自定义的字符串生成state..."); - String stringBody = "这是一个字符串"; - String stringState = AuthState.create(source, stringBody); - System.out.println(stringState); - stringBody = AuthState.getBody(source, stringState, String.class); - System.out.println(stringBody); - AuthState.delete(source); - - System.out.println("\n通过传入数字生成state..."); - Integer numberBody = 111; - String numberState = AuthState.create(source, numberBody); - System.out.println(numberState); - numberBody = AuthState.getBody(source, numberState, Integer.class); - System.out.println(numberBody); - 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); - dateBody = AuthState.getBody(source, dateState, Date.class); - System.out.println(dateBody); - AuthState.delete(source); - - System.out.println("\n通过传入map生成state..."); - Map mapBody = new HashMap<>(); - mapBody.put("userId", 1); - mapBody.put("userToken", "xxxxx"); - String mapState = AuthState.create(source, mapBody); - System.out.println(mapState); - mapBody = AuthState.getBody(source, mapState, Map.class); - System.out.println(mapBody); - AuthState.delete(source); - - System.out.println("\n通过传入List生成state..."); - List listBody = new ArrayList<>(); - listBody.add("xxxx"); - listBody.add("xxxxxxxx"); - String listState = AuthState.create(source, listBody); - System.out.println(listState); - listBody = AuthState.getBody(source, listState, List.class); - System.out.println(listBody); - AuthState.delete(source); - - System.out.println("\n通过传入实体类生成state..."); - AuthConfig entityBody = AuthConfig.builder() - .clientId("xxxxx") - .clientSecret("xxxxx") - .build(); - String entityState = AuthState.create(source, entityBody); - System.out.println(entityState); - entityBody = AuthState.getBody(source, entityState, AuthConfig.class); - System.out.println(entityBody); - AuthState.delete(source); - } - - @Test - public void getErrorStateBody() { - String source = "github"; - String state = "1111111111111111111111111111111"; - String body = AuthState.getBody(source, state, String.class); - System.out.println(body); - AuthState.delete(source); - } -} \ No newline at end of file diff --git a/src/test/java/me/zhyd/oauth/utils/UrlBuilderTest.java b/src/test/java/me/zhyd/oauth/utils/UrlBuilderTest.java index 161031e08f1e5d4dd4f6c453a14f37366539363b..065c59acc2521f0b29314e9a32259b3fbeff7387 100644 --- a/src/test/java/me/zhyd/oauth/utils/UrlBuilderTest.java +++ b/src/test/java/me/zhyd/oauth/utils/UrlBuilderTest.java @@ -3,7 +3,6 @@ package me.zhyd.oauth.utils; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; import me.zhyd.oauth.request.AuthWeChatRequest; -import org.junit.Assert; import org.junit.Test; /** @@ -21,18 +20,17 @@ public class UrlBuilderTest { .clientId("appid-110110110") .clientSecret("secret-110110110") .redirectUri("https://xkcoding.com") - .state(AuthState.create(AuthSource.WECHAT)) .build(); String build = UrlBuilder.fromBaseUrl(AuthSource.WECHAT.authorize()) .queryParam("appid", config.getClientId()) .queryParam("redirect_uri", config.getRedirectUri()) .queryParam("response_type", "code") .queryParam("scope", "snsapi_login") - .queryParam("state", config.getState().concat("#wechat_redirect")) + .queryParam("state", "") .build(false); + System.out.println(build); AuthWeChatRequest request = new AuthWeChatRequest(config); - String authorize = request.authorize(); - Assert.assertEquals(build, authorize); - AuthState.delete(AuthSource.WECHAT); + String authorize = request.authorize("state"); + System.out.println(authorize); } }