diff --git a/spring-boot-demo-social/pom.xml b/spring-boot-demo-social/pom.xml index 82b2bde..4960ecf 100644 --- a/spring-boot-demo-social/pom.xml +++ b/spring-boot-demo-social/pom.xml @@ -20,7 +20,7 @@ UTF-8 UTF-8 1.8 - 1.1.6.RELEASE + 1.0.0 @@ -35,11 +35,22 @@ test + + org.springframework.boot + spring-boot-starter-data-redis + + + + + org.apache.commons + commons-pool2 + + - me.zhyd.oauth - JustAuth - 1.9.5 + com.xkcoding + justauth-spring-boot-starter + ${justauth-spring-boot.version} diff --git a/spring-boot-demo-social/src/main/java/com/xkcoding/social/SpringBootDemoSocialApplication.java b/spring-boot-demo-social/src/main/java/com/xkcoding/social/SpringBootDemoSocialApplication.java index 3369558..595960f 100644 --- a/spring-boot-demo-social/src/main/java/com/xkcoding/social/SpringBootDemoSocialApplication.java +++ b/spring-boot-demo-social/src/main/java/com/xkcoding/social/SpringBootDemoSocialApplication.java @@ -8,13 +8,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; * 启动器 *

* - * @package: com.xkcoding.social - * @description: 启动器 - * @author: yangkai.shen - * @date: Created in 2019-02-19 16:04 - * @copyright: Copyright (c) 2019 - * @version: V1.0 - * @modified: yangkai.shen + * @author yangkai.shen + * @date Created in 2019-08-09 13:51 */ @SpringBootApplication public class SpringBootDemoSocialApplication { diff --git a/spring-boot-demo-social/src/main/java/com/xkcoding/social/config/justauth/JustAuthConfig.java b/spring-boot-demo-social/src/main/java/com/xkcoding/social/config/justauth/JustAuthConfig.java new file mode 100644 index 0000000..eb346da --- /dev/null +++ b/spring-boot-demo-social/src/main/java/com/xkcoding/social/config/justauth/JustAuthConfig.java @@ -0,0 +1,39 @@ +package com.xkcoding.social.config.justauth; + +import me.zhyd.oauth.cache.AuthStateCache; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import java.io.Serializable; + +/** + *

+ * JustAuth自动装配 + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-09 14:21 + */ +@Configuration +public class JustAuthConfig { + /** + * 默认情况下的模板只能支持RedisTemplate,也就是只能存入字符串,因此支持序列化 + */ + @Bean + public RedisTemplate redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + template.setKeySerializer(new StringRedisSerializer()); + template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + template.setConnectionFactory(redisConnectionFactory); + return template; + } + + @Bean + public AuthStateCache authStateCache(RedisTemplate redisCacheTemplate) { + return new JustAuthRedisStateCache(redisCacheTemplate); + } +} \ No newline at end of file diff --git a/spring-boot-demo-social/src/main/java/com/xkcoding/social/config/justauth/JustAuthRedisStateCache.java b/spring-boot-demo-social/src/main/java/com/xkcoding/social/config/justauth/JustAuthRedisStateCache.java new file mode 100644 index 0000000..cec2fb7 --- /dev/null +++ b/spring-boot-demo-social/src/main/java/com/xkcoding/social/config/justauth/JustAuthRedisStateCache.java @@ -0,0 +1,70 @@ +package com.xkcoding.social.config.justauth; + +import lombok.RequiredArgsConstructor; +import me.zhyd.oauth.cache.AuthStateCache; +import org.springframework.data.redis.core.RedisTemplate; + +import java.util.concurrent.TimeUnit; + +/** + *

+ * Redis作为JustAuth的State的缓存 + *

+ * + * @author yangkai.shen + * @date Created in 2019-08-09 14:22 + */ +@RequiredArgsConstructor +public class JustAuthRedisStateCache implements AuthStateCache { + private final RedisTemplate redisTemplate; + private static final long DEF_TIMEOUT = 3 * 60 * 1000; + + /** + * 存入缓存 + * + * @param key 缓存key + * @param value 缓存内容 + */ + @Override + public void cache(String key, String value) { + this.cache(key, value, DEF_TIMEOUT); + } + + /** + * 存入缓存 + * + * @param key 缓存key + * @param value 缓存内容 + * @param timeout 指定缓存过期时间(毫秒) + */ + @Override + public void cache(String key, String value, long timeout) { + redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.MILLISECONDS); + } + + /** + * 获取缓存内容 + * + * @param key 缓存key + * @return 缓存内容 + */ + @Override + public String get(String key) { + return redisTemplate.opsForValue().get(key); + } + + /** + * 是否存在key,如果对应key的value值已过期,也返回false + * + * @param key 缓存key + * @return true:存在key,并且value没过期;false:key不存在或者已过期 + */ + @Override + public boolean containsKey(String key) { + Long expire = redisTemplate.getExpire(key, TimeUnit.MILLISECONDS); + if (expire == null) { + expire = 0L; + } + return expire > 0; + } +} diff --git a/spring-boot-demo-social/src/main/java/com/xkcoding/social/controller/OauthController.java b/spring-boot-demo-social/src/main/java/com/xkcoding/social/controller/OauthController.java index 7dc3cec..f780d37 100644 --- a/spring-boot-demo-social/src/main/java/com/xkcoding/social/controller/OauthController.java +++ b/spring-boot-demo-social/src/main/java/com/xkcoding/social/controller/OauthController.java @@ -1,15 +1,14 @@ package com.xkcoding.social.controller; -import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; -import com.xkcoding.social.props.OAuthProperties; +import com.xkcoding.justauth.AuthRequestFactory; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; import me.zhyd.oauth.model.AuthCallback; import me.zhyd.oauth.model.AuthResponse; -import me.zhyd.oauth.request.*; +import me.zhyd.oauth.request.AuthRequest; import me.zhyd.oauth.utils.AuthStateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -19,6 +18,9 @@ import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** *

@@ -38,14 +40,15 @@ import java.io.IOException; @RequestMapping("/oauth") @RequiredArgsConstructor(onConstructor_ = @Autowired) public class OauthController { - private final OAuthProperties properties; + private final AuthRequestFactory factory; /** * 登录类型 */ @GetMapping - public Dict loginType() { - return Dict.create().set("QQ登录", "http://oauth.xkcoding.com/demo/oauth/login/qq").set("GitHub登录", "http://oauth.xkcoding.com/demo/oauth/login/github").set("微信登录", "http://oauth.xkcoding.com/demo/oauth/login/wechat").set("Google登录", "http://oauth.xkcoding.com/demo/oauth/login/google").set("Microsoft 登录", "http://oauth.xkcoding.com/demo/oauth/login/microsoft").set("小米登录", "http://oauth.xkcoding.com/demo/oauth/login/mi"); + public Map loginType() { + List oauthList = factory.oauthList(); + return oauthList.stream().collect(Collectors.toMap(oauth -> oauth.toLowerCase() + "登录", oauth -> "http://oauth.xkcoding.com/demo/oauth/login/" + oauth.toLowerCase())); } /** @@ -57,8 +60,8 @@ public class OauthController { */ @RequestMapping("/login/{oauthType}") public void renderAuth(@PathVariable String oauthType, HttpServletResponse response) throws IOException { - AuthRequest authRequest = getAuthRequest(oauthType); - response.sendRedirect(authRequest.authorize(AuthStateUtils.createState())); + AuthRequest authRequest = factory.get(getAuthSource(oauthType)); + response.sendRedirect(authRequest.authorize(oauthType + "::" + AuthStateUtils.createState())); } /** @@ -70,59 +73,17 @@ public class OauthController { */ @RequestMapping("/{oauthType}/callback") public AuthResponse login(@PathVariable String oauthType, AuthCallback callback) { - AuthRequest authRequest = getAuthRequest(oauthType); + AuthRequest authRequest = factory.get(getAuthSource(oauthType)); AuthResponse response = authRequest.login(callback); log.info("【response】= {}", JSONUtil.toJsonStr(response)); return response; } - private AuthRequest getAuthRequest(String oauthType) { - AuthSource authSource = AuthSource.valueOf(oauthType.toUpperCase()); - switch (authSource) { - case QQ: - return getQqAuthRequest(); - case GITHUB: - return getGithubAuthRequest(); - case WECHAT: - return getWechatAuthRequest(); - case GOOGLE: - return getGoogleAuthRequest(); - case MICROSOFT: - return getMicrosoftAuthRequest(); - case MI: - return getMiAuthRequest(); - default: - throw new RuntimeException("暂不支持的第三方登录"); + private AuthSource getAuthSource(String type) { + if (StrUtil.isNotBlank(type)) { + return AuthSource.valueOf(type.toUpperCase()); + } else { + throw new RuntimeException("不支持的类型"); } } - - private AuthRequest getQqAuthRequest() { - AuthConfig authConfig = properties.getQq(); - return new AuthQqRequest(authConfig); - } - - private AuthRequest getGithubAuthRequest() { - AuthConfig authConfig = properties.getGithub(); - return new AuthGithubRequest(authConfig); - } - - private AuthRequest getWechatAuthRequest() { - AuthConfig authConfig = properties.getWechat(); - return new AuthWeChatRequest(authConfig); - } - - private AuthRequest getGoogleAuthRequest() { - AuthConfig authConfig = properties.getGoogle(); - return new AuthGoogleRequest(authConfig); - } - - private AuthRequest getMicrosoftAuthRequest() { - AuthConfig authConfig = properties.getMicrosoft(); - return new AuthMicrosoftRequest(authConfig); - } - - private AuthRequest getMiAuthRequest() { - AuthConfig authConfig = properties.getMi(); - return new AuthMiRequest(authConfig); - } } diff --git a/spring-boot-demo-social/src/main/java/com/xkcoding/social/props/OAuthProperties.java b/spring-boot-demo-social/src/main/java/com/xkcoding/social/props/OAuthProperties.java deleted file mode 100644 index 45e562b..0000000 --- a/spring-boot-demo-social/src/main/java/com/xkcoding/social/props/OAuthProperties.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.xkcoding.social.props; - -import lombok.Data; -import me.zhyd.oauth.config.AuthConfig; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -/** - *

- * 第三方登录配置 - *

- * - * @package: com.xkcoding.oauth.config.props - * @description: 第三方登录配置 - * @author: yangkai.shen - * @date: Created in 2019-05-17 15:33 - * @copyright: Copyright (c) 2019 - * @version: V1.0 - * @modified: yangkai.shen - */ -@Data -@Component -@ConfigurationProperties(prefix = "oauth") -public class OAuthProperties { - /** - * QQ 配置 - */ - private AuthConfig qq; - - /** - * github 配置 - */ - private AuthConfig github; - - /** - * 微信 配置 - */ - private AuthConfig wechat; - - /** - * Google 配置 - */ - private AuthConfig google; - - /** - * Microsoft 配置 - */ - private AuthConfig microsoft; - - /** - * Mi 配置 - */ - private AuthConfig mi; -} diff --git a/spring-boot-demo-social/src/main/resources/application.yml b/spring-boot-demo-social/src/main/resources/application.yml index b790f53..0cd5592 100644 --- a/spring-boot-demo-social/src/main/resources/application.yml +++ b/spring-boot-demo-social/src/main/resources/application.yml @@ -3,6 +3,27 @@ server: servlet: context-path: /demo +spring: + redis: + host: localhost + # 连接超时时间(记得添加单位,Duration) + timeout: 10000ms + # Redis默认情况下有16个分片,这里配置具体使用的分片 + # database: 0 + lettuce: + pool: + # 连接池最大连接数(使用负值表示没有限制) 默认 8 + max-active: 8 + # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 + max-wait: -1ms + # 连接池中的最大空闲连接 默认 8 + max-idle: 8 + # 连接池中的最小空闲连接 默认 0 + min-idle: 0 + cache: + # 一般来说是不用配置的,Spring Cache 会根据依赖的包自行装配 + type: redis + oauth: qq: client-id: 1015***** @@ -28,3 +49,8 @@ oauth: client-id: 2882303************** client-secret: nFeTt89Yn************** redirect-uri: http://oauth.xkcoding.com/demo/oauth/mi/callback + wechat_enterprise: + client-id: ww58**********6fbc + client-secret: 8G6PCr0****************************yzaPc78 + redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_enterprise/callback + agent-id: 10*******02 \ No newline at end of file