Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ea383ee

Browse files
committed
⬆️ 使用 justauth-spring-boot-starter 实现第三方登录,同时缓存使用自定义 redis 缓存 state
1 parent 23d65a8 commit ea383ee

File tree

7 files changed

+170
-122
lines changed

7 files changed

+170
-122
lines changed

‎spring-boot-demo-social/pom.xml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
2121
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
2222
<java.version>1.8</java.version>
23-
<spring.social.version>1.1.6.RELEASE</spring.social.version>
23+
<justauth-spring-boot.version>1.0.0</justauth-spring-boot.version>
2424
</properties>
2525

2626
<dependencies>
@@ -35,11 +35,22 @@
3535
<scope>test</scope>
3636
</dependency>
3737

38+
<dependency>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-starter-data-redis</artifactId>
41+
</dependency>
42+
43+
<!-- 对象池,使用redis时必须引入 -->
44+
<dependency>
45+
<groupId>org.apache.commons</groupId>
46+
<artifactId>commons-pool2</artifactId>
47+
</dependency>
48+
3849
<!-- oauth工具类 -->
3950
<dependency>
40-
<groupId>me.zhyd.oauth</groupId>
41-
<artifactId>JustAuth</artifactId>
42-
<version>1.9.5</version>
51+
<groupId>com.xkcoding</groupId>
52+
<artifactId>justauth-spring-boot-starter</artifactId>
53+
<version>${justauth-spring-boot.version}</version>
4354
</dependency>
4455

4556
<dependency>

‎spring-boot-demo-social/src/main/java/com/xkcoding/social/SpringBootDemoSocialApplication.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,8 @@
88
* 启动器
99
* </p>
1010
*
11-
* @package: com.xkcoding.social
12-
* @description: 启动器
13-
* @author: yangkai.shen
14-
* @date: Created in 2019年02月19日 16:04
15-
* @copyright: Copyright (c) 2019
16-
* @version: V1.0
17-
* @modified: yangkai.shen
11+
* @author yangkai.shen
12+
* @date Created in 2019年08月09日 13:51
1813
*/
1914
@SpringBootApplication
2015
public class SpringBootDemoSocialApplication {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.xkcoding.social.config.justauth;
2+
3+
import me.zhyd.oauth.cache.AuthStateCache;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
7+
import org.springframework.data.redis.core.RedisTemplate;
8+
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
9+
import org.springframework.data.redis.serializer.StringRedisSerializer;
10+
11+
import java.io.Serializable;
12+
13+
/**
14+
* <p>
15+
* JustAuth自动装配
16+
* </p>
17+
*
18+
* @author yangkai.shen
19+
* @date Created in 2019年08月09日 14:21
20+
*/
21+
@Configuration
22+
public class JustAuthConfig {
23+
/**
24+
* 默认情况下的模板只能支持RedisTemplate<String, String>,也就是只能存入字符串,因此支持序列化
25+
*/
26+
@Bean
27+
public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
28+
RedisTemplate<String, Serializable> template = new RedisTemplate<>();
29+
template.setKeySerializer(new StringRedisSerializer());
30+
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
31+
template.setConnectionFactory(redisConnectionFactory);
32+
return template;
33+
}
34+
35+
@Bean
36+
public AuthStateCache authStateCache(RedisTemplate<String, String> redisCacheTemplate) {
37+
return new JustAuthRedisStateCache(redisCacheTemplate);
38+
}
39+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.xkcoding.social.config.justauth;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import me.zhyd.oauth.cache.AuthStateCache;
5+
import org.springframework.data.redis.core.RedisTemplate;
6+
7+
import java.util.concurrent.TimeUnit;
8+
9+
/**
10+
* <p>
11+
* Redis作为JustAuth的State的缓存
12+
* </p>
13+
*
14+
* @author yangkai.shen
15+
* @date Created in 2019年08月09日 14:22
16+
*/
17+
@RequiredArgsConstructor
18+
public class JustAuthRedisStateCache implements AuthStateCache {
19+
private final RedisTemplate<String, String> redisTemplate;
20+
private static final long DEF_TIMEOUT = 3 * 60 * 1000;
21+
22+
/**
23+
* 存入缓存
24+
*
25+
* @param key 缓存key
26+
* @param value 缓存内容
27+
*/
28+
@Override
29+
public void cache(String key, String value) {
30+
this.cache(key, value, DEF_TIMEOUT);
31+
}
32+
33+
/**
34+
* 存入缓存
35+
*
36+
* @param key 缓存key
37+
* @param value 缓存内容
38+
* @param timeout 指定缓存过期时间(毫秒)
39+
*/
40+
@Override
41+
public void cache(String key, String value, long timeout) {
42+
redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.MILLISECONDS);
43+
}
44+
45+
/**
46+
* 获取缓存内容
47+
*
48+
* @param key 缓存key
49+
* @return 缓存内容
50+
*/
51+
@Override
52+
public String get(String key) {
53+
return redisTemplate.opsForValue().get(key);
54+
}
55+
56+
/**
57+
* 是否存在key,如果对应key的value值已过期,也返回false
58+
*
59+
* @param key 缓存key
60+
* @return true:存在key,并且value没过期;false:key不存在或者已过期
61+
*/
62+
@Override
63+
public boolean containsKey(String key) {
64+
Long expire = redisTemplate.getExpire(key, TimeUnit.MILLISECONDS);
65+
if (expire == null) {
66+
expire = 0L;
67+
}
68+
return expire > 0;
69+
}
70+
}
Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package com.xkcoding.social.controller;
22

3-
import cn.hutool.core.lang.Dict;
3+
import cn.hutool.core.util.StrUtil;
44
import cn.hutool.json.JSONUtil;
5-
import com.xkcoding.social.props.OAuthProperties;
5+
import com.xkcoding.justauth.AuthRequestFactory;
66
import lombok.RequiredArgsConstructor;
77
import lombok.extern.slf4j.Slf4j;
8-
import me.zhyd.oauth.config.AuthConfig;
98
import me.zhyd.oauth.config.AuthSource;
109
import me.zhyd.oauth.model.AuthCallback;
1110
import me.zhyd.oauth.model.AuthResponse;
12-
import me.zhyd.oauth.request.*;
11+
import me.zhyd.oauth.request.AuthRequest;
1312
import me.zhyd.oauth.utils.AuthStateUtils;
1413
import org.springframework.beans.factory.annotation.Autowired;
1514
import org.springframework.web.bind.annotation.GetMapping;
@@ -19,6 +18,9 @@
1918

2019
import javax.servlet.http.HttpServletResponse;
2120
import java.io.IOException;
21+
import java.util.List;
22+
import java.util.Map;
23+
import java.util.stream.Collectors;
2224

2325
/**
2426
* <p>
@@ -38,14 +40,15 @@
3840
@RequestMapping("/oauth")
3941
@RequiredArgsConstructor(onConstructor_ = @Autowired)
4042
public class OauthController {
41-
private final OAuthPropertiesproperties;
43+
private final AuthRequestFactoryfactory;
4244

4345
/**
4446
* 登录类型
4547
*/
4648
@GetMapping
47-
public Dict loginType() {
48-
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");
49+
public Map<String, String> loginType() {
50+
List<String> oauthList = factory.oauthList();
51+
return oauthList.stream().collect(Collectors.toMap(oauth -> oauth.toLowerCase() + "登录", oauth -> "http://oauth.xkcoding.com/demo/oauth/login/" + oauth.toLowerCase()));
4952
}
5053

5154
/**
@@ -57,8 +60,8 @@ public Dict loginType() {
5760
*/
5861
@RequestMapping("/login/{oauthType}")
5962
public void renderAuth(@PathVariable String oauthType, HttpServletResponse response) throws IOException {
60-
AuthRequest authRequest = getAuthRequest(oauthType);
61-
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
63+
AuthRequest authRequest = factory.get(getAuthSource(oauthType));
64+
response.sendRedirect(authRequest.authorize(oauthType + "::" + AuthStateUtils.createState()));
6265
}
6366

6467
/**
@@ -70,59 +73,17 @@ public void renderAuth(@PathVariable String oauthType, HttpServletResponse respo
7073
*/
7174
@RequestMapping("/{oauthType}/callback")
7275
public AuthResponse login(@PathVariable String oauthType, AuthCallback callback) {
73-
AuthRequest authRequest = getAuthRequest(oauthType);
76+
AuthRequest authRequest = factory.get(getAuthSource(oauthType));
7477
AuthResponse response = authRequest.login(callback);
7578
log.info("【response】= {}", JSONUtil.toJsonStr(response));
7679
return response;
7780
}
7881

79-
private AuthRequest getAuthRequest(String oauthType) {
80-
AuthSource authSource = AuthSource.valueOf(oauthType.toUpperCase());
81-
switch (authSource) {
82-
case QQ:
83-
return getQqAuthRequest();
84-
case GITHUB:
85-
return getGithubAuthRequest();
86-
case WECHAT:
87-
return getWechatAuthRequest();
88-
case GOOGLE:
89-
return getGoogleAuthRequest();
90-
case MICROSOFT:
91-
return getMicrosoftAuthRequest();
92-
case MI:
93-
return getMiAuthRequest();
94-
default:
95-
throw new RuntimeException("暂不支持的第三方登录");
82+
private AuthSource getAuthSource(String type) {
83+
if (StrUtil.isNotBlank(type)) {
84+
return AuthSource.valueOf(type.toUpperCase());
85+
} else {
86+
throw new RuntimeException("不支持的类型");
9687
}
9788
}
98-
99-
private AuthRequest getQqAuthRequest() {
100-
AuthConfig authConfig = properties.getQq();
101-
return new AuthQqRequest(authConfig);
102-
}
103-
104-
private AuthRequest getGithubAuthRequest() {
105-
AuthConfig authConfig = properties.getGithub();
106-
return new AuthGithubRequest(authConfig);
107-
}
108-
109-
private AuthRequest getWechatAuthRequest() {
110-
AuthConfig authConfig = properties.getWechat();
111-
return new AuthWeChatRequest(authConfig);
112-
}
113-
114-
private AuthRequest getGoogleAuthRequest() {
115-
AuthConfig authConfig = properties.getGoogle();
116-
return new AuthGoogleRequest(authConfig);
117-
}
118-
119-
private AuthRequest getMicrosoftAuthRequest() {
120-
AuthConfig authConfig = properties.getMicrosoft();
121-
return new AuthMicrosoftRequest(authConfig);
122-
}
123-
124-
private AuthRequest getMiAuthRequest() {
125-
AuthConfig authConfig = properties.getMi();
126-
return new AuthMiRequest(authConfig);
127-
}
12889
}

‎spring-boot-demo-social/src/main/java/com/xkcoding/social/props/OAuthProperties.java

Lines changed: 0 additions & 54 deletions
This file was deleted.

‎spring-boot-demo-social/src/main/resources/application.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,27 @@ server:
33
servlet:
44
context-path: /demo
55

6+
spring:
7+
redis:
8+
host: localhost
9+
# 连接超时时间(记得添加单位,Duration)
10+
timeout: 10000ms
11+
# Redis默认情况下有16个分片,这里配置具体使用的分片
12+
# database: 0
13+
lettuce:
14+
pool:
15+
# 连接池最大连接数(使用负值表示没有限制) 默认 8
16+
max-active: 8
17+
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
18+
max-wait: -1ms
19+
# 连接池中的最大空闲连接 默认 8
20+
max-idle: 8
21+
# 连接池中的最小空闲连接 默认 0
22+
min-idle: 0
23+
cache:
24+
# 一般来说是不用配置的,Spring Cache 会根据依赖的包自行装配
25+
type: redis
26+
627
oauth:
728
qq:
829
client-id: 1015*****
@@ -28,3 +49,8 @@ oauth:
2849
client-id: 2882303**************
2950
client-secret: nFeTt89Yn**************
3051
redirect-uri: http://oauth.xkcoding.com/demo/oauth/mi/callback
52+
wechat_enterprise:
53+
client-id: ww58**********6fbc
54+
client-secret: 8G6PCr0****************************yzaPc78
55+
redirect-uri: http://oauth.xkcoding.com/demo/oauth/wechat_enterprise/callback
56+
agent-id: 10*******02

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /