From 962ea083f0bf2edb86a4b59afe0f71e5f4dae8f9 Mon Sep 17 00:00:00 2001
From: weiyachao <13526234727@126.com>
Date: Thu, 21 Sep 2023 18:24:27 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=99=BB=E5=BD=95=E6=8B=A6?=
=?UTF-8?q?=E6=88=AA=E5=99=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/qiuguo/iot/base/annotation/Auth.java | 18 -----
iot-gateway/pom.xml | 10 +++
.../config/GlobalCorsConfiguration.java | 8 +--
.../config/properties/CorsProperties.java | 2 +-
.../qiuguo/iot/gateway/filter/AuthFilter.java | 69 +++++++++++++++++++
iot-gateway/src/main/resources/bootstrap.yml | 31 +++++++++
.../api/controller/user/UserController.java | 52 +++++++++-----
.../iot/user/api/filter/AuthFilter.java | 12 ----
.../src/main/resources/bootstrap.yml | 4 +-
.../src/test/java/UserTest.java | 4 +-
10 files changed, 155 insertions(+), 55 deletions(-)
delete mode 100644 iot-common/iot-base/src/main/java/com/qiuguo/iot/base/annotation/Auth.java
create mode 100644 iot-gateway/src/main/java/com/qiuguo/iot/gateway/filter/AuthFilter.java
diff --git a/iot-common/iot-base/src/main/java/com/qiuguo/iot/base/annotation/Auth.java b/iot-common/iot-base/src/main/java/com/qiuguo/iot/base/annotation/Auth.java
deleted file mode 100644
index f7dbd36..0000000
--- a/iot-common/iot-base/src/main/java/com/qiuguo/iot/base/annotation/Auth.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.qiuguo.iot.base.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 强制登陆
- *
- * @author weiyachao
- * @since 2023/9/20 15:55
- */
-@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Auth {
-
-}
diff --git a/iot-gateway/pom.xml b/iot-gateway/pom.xml
index 6e514d6..04ecd3d 100644
--- a/iot-gateway/pom.xml
+++ b/iot-gateway/pom.xml
@@ -59,6 +59,16 @@
1.2.83
compile
+
+ org.springframework.boot
+ spring-boot-starter-data-redis-reactive
+
+
+ com.qiuguo.iot
+ iot-base
+ 0.0.1-SNAPSHOT
+ compile
+
diff --git a/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/GlobalCorsConfiguration.java b/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/GlobalCorsConfiguration.java
index 7810bbd..dfb0065 100644
--- a/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/GlobalCorsConfiguration.java
+++ b/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/GlobalCorsConfiguration.java
@@ -13,8 +13,8 @@ import org.springframework.web.filter.CorsFilter;
* 全局跨域配置.
*
*/
-@AutoConfiguration
-@EnableConfigurationProperties(CorsProperties.class)
+// @AutoConfiguration
+// @EnableConfigurationProperties(CorsProperties.class)
public class GlobalCorsConfiguration {
/**
@@ -22,8 +22,8 @@ public class GlobalCorsConfiguration {
*
* @param corsProperties 跨域配置
*/
- @Bean
- @ConditionalOnMissingBean(CorsFilter.class)
+ // @Bean
+ // @ConditionalOnMissingBean(CorsFilter.class)
public CorsFilter corsFilter(CorsProperties corsProperties) {
CorsConfiguration config = new CorsConfiguration();
// 设置允许跨域访问的域名
diff --git a/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/properties/CorsProperties.java b/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/properties/CorsProperties.java
index a0ef19d..e9368e5 100644
--- a/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/properties/CorsProperties.java
+++ b/iot-gateway/src/main/java/com/qiuguo/iot/gateway/config/properties/CorsProperties.java
@@ -13,7 +13,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
*/
@Getter
@Setter
-@ConfigurationProperties(prefix = "application.cors")
+// @ConfigurationProperties(prefix = "application.cors")
public class CorsProperties {
/**
diff --git a/iot-gateway/src/main/java/com/qiuguo/iot/gateway/filter/AuthFilter.java b/iot-gateway/src/main/java/com/qiuguo/iot/gateway/filter/AuthFilter.java
new file mode 100644
index 0000000..3d9791d
--- /dev/null
+++ b/iot-gateway/src/main/java/com/qiuguo/iot/gateway/filter/AuthFilter.java
@@ -0,0 +1,69 @@
+package com.qiuguo.iot.gateway.filter;
+
+import com.qiuguo.iot.base.constans.RedisConstans;
+import com.qiuguo.iot.base.constans.UserAuthContains;
+import com.qiuguo.iot.gateway.config.properties.XssProperties;
+import java.time.Duration;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cloud.gateway.filter.GatewayFilterChain;
+import org.springframework.cloud.gateway.filter.GlobalFilter;
+import org.springframework.core.Ordered;
+import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
+import org.springframework.http.server.RequestPath;
+import org.springframework.http.server.reactive.ServerHttpRequest;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.server.ServerWebExchange;
+import reactor.core.publisher.Mono;
+
+/**
+ * XXX
+ *
+ * @author weiyachao
+ * @since 2023/9/21 17:56
+ */
+@Component
+@Slf4j
+public class AuthFilter implements GlobalFilter, Ordered {
+
+ @Autowired
+ private ReactiveStringRedisTemplate reactiveRedisTemplate;
+
+ @Autowired
+ private XssProperties xssProperties;
+
+ @Override
+ public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
+ ServerHttpRequest request = exchange.getRequest();
+ String url = request.getURI().toString();
+ if (xssProperties.getExcludeUrls().contains(url)) {
+ return chain.filter(exchange);
+ }
+
+ String api_token = exchange.getRequest().getHeaders().getFirst(UserAuthContains.API_TOKEN);
+ String api_type = exchange.getRequest().getHeaders().getFirst(UserAuthContains.API_TYPE);
+ if (ObjectUtils.isEmpty(api_token) || ObjectUtils.isEmpty(api_type)) {
+ return Mono.error(new RuntimeException("未登录"));
+ }
+ String key = RedisConstans.IOT_TOKEN.concat(api_token);
+ return reactiveRedisTemplate.getExpire(key).map(Duration::getSeconds).flatMap(ttl -> {
+ if (ttl == -1) {
+ // 用户没登陆
+ return Mono.error(new RuntimeException("未登录"));
+ } else if (ttl <= 3600) {
+ // token 将要失效
+ return reactiveRedisTemplate.expire(key, Duration.ofDays(7)).then(chain.filter(exchange));
+ } else {
+ // 正常登录
+ return chain.filter(exchange);
+ }
+ });
+ }
+
+
+ @Override
+ public int getOrder() {
+ return -1;
+ }
+}
diff --git a/iot-gateway/src/main/resources/bootstrap.yml b/iot-gateway/src/main/resources/bootstrap.yml
index 8efac3c..b854733 100644
--- a/iot-gateway/src/main/resources/bootstrap.yml
+++ b/iot-gateway/src/main/resources/bootstrap.yml
@@ -19,4 +19,35 @@ spring:
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
+ gateway:
+ discovery:
+ locator:
+ # 开启服务发现
+ enabled: true
+ # 忽略注册中心服务的大小写
+ lower-case-service-id: true
+ globalcors:
+ corsConfigurations:
+ '[/**]':
+ # 允许携带认证信息
+ allow-credentials: true
+ # 允许跨域的源(网站域名/ip),设置*为全部
+ allowedOriginPatterns: "*"
+ # 允许跨域的method, 默认为GET和OPTIONS,设置*为全部
+ allowedMethods: "*"
+ # 允许跨域请求里的head字段,设置*为全部
+ allowedHeaders: "*"
+ routes:
+
+# 安全配置
+security:
+ # 防止XSS攻击
+ xss:
+ enabled: true
+ # 排除的路径
+ exclude-urls:
+ - /ehs-audit/web/audit-content
+application:
+ cors:
+ allowed-crigin-patterns:
diff --git a/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/controller/user/UserController.java b/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/controller/user/UserController.java
index 1d31b5e..a99c9b0 100644
--- a/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/controller/user/UserController.java
+++ b/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/controller/user/UserController.java
@@ -1,9 +1,16 @@
package com.qiuguo.iot.user.api.controller.user;
import com.alibaba.fastjson.JSONObject;
+import com.qiuguo.iot.base.constans.RedisConstans;
+import com.qiuguo.iot.base.constans.UserAuthContains;
+import java.time.Duration;
import java.util.Objects;
+import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.ReactiveRedisTemplate;
+import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -31,7 +38,7 @@ import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VAL
public class UserController {
private final WebClient webClient = WebClient.builder()
.defaultHeader(HttpHeaders.CONTENT_TYPE,APPLICATION_FORM_URLENCODED_VALUE)
- .defaultHeader("Api-Type","web")
+ .defaultHeader("Api-Type","iot")
.build();
@Value("${userUrl.baseUrl}")
@@ -64,12 +71,15 @@ public class UserController {
@Value("${userUrl.editUserInfoUrl}")
private String editUserInfoUrl;
+ @Resource
+ private ReactiveStringRedisTemplate reactiveStringRedisTemplate;
+
/**
* 修改登录密码-auth
*/
@PostMapping("/change")
- public Mono change(@RequestBody JSONObject jsonObject, @RequestHeader("Api-Token") String token,
- @RequestHeader("Api-Type") String type) {
+ public Mono change(@RequestBody JSONObject jsonObject, @RequestHeader(UserAuthContains.API_TOKEN) String token,
+ @RequestHeader(UserAuthContains.API_TYPE) String type) {
WebClient authWebClient = getAuthWebClient(token, type);
return authWebClient.post().uri(baseUrl + changeUrl).bodyValue(getMultiValueMap(jsonObject)).retrieve()
.bodyToMono(JSONObject.class).doOnNext(res -> {
@@ -83,8 +93,8 @@ public class UserController {
* 账号注销-auth
*/
@PostMapping("/userCance")
- public Mono userCance(@RequestBody JSONObject jsonObject, @RequestHeader("Api-Token") String token,
- @RequestHeader("Api-Type") String type) {
+ public Mono userCance(@RequestBody JSONObject jsonObject, @RequestHeader(UserAuthContains.API_TOKEN) String token,
+ @RequestHeader(UserAuthContains.API_TYPE) String type) {
return getAuthWebClient(token, type).post().uri(baseUrl + userCancelUrl)
.bodyValue(getMultiValueMap(jsonObject))
.retrieve()
@@ -99,8 +109,8 @@ public class UserController {
* 修改用户信息-auth
*/
@PostMapping("/edit/userInfo")
- public Mono editUserInfo(@RequestBody JSONObject jsonObject, @RequestHeader("Api-Token") String token,
- @RequestHeader("Api-Type") String type) {
+ public Mono editUserInfo(@RequestBody JSONObject jsonObject, @RequestHeader(UserAuthContains.API_TOKEN) String token,
+ @RequestHeader(UserAuthContains.API_TYPE) String type) {
return webClient.mutate()
.defaultHeader("Api-Token", token)
.defaultHeader("Api-Type", type).build().post().uri(editUserInfoUrl)
@@ -117,8 +127,8 @@ public class UserController {
* 个人信息管理-auth
*/
@GetMapping("/userInfo")
- public Mono getUserInfo(@RequestHeader("Api-Token") String token,
- @RequestHeader("Api-Type") String type) {
+ public Mono getUserInfo(@RequestHeader(UserAuthContains.API_TOKEN) String token,
+ @RequestHeader(UserAuthContains.API_TYPE) String type) {
return getAuthWebClient(token, type).get().uri(userInfoUrl).retrieve()
.bodyToMono(JSONObject.class).doOnNext(res -> {
if (!Objects.equals(res.getInteger("code"), 200)) {
@@ -131,8 +141,8 @@ public class UserController {
* 是否设置登录密码-auth
*/
@GetMapping("/first/password")
- public Mono firstPassword(@RequestHeader("Api-Token") String token,
- @RequestHeader("Api-Type") String type) {
+ public Mono firstPassword(@RequestHeader(UserAuthContains.API_TOKEN) String token,
+ @RequestHeader(UserAuthContains.API_TYPE) String type) {
return getAuthWebClient(token, type).get().uri(firstPasswordUrl).retrieve()
.bodyToMono(JSONObject.class).doOnNext(res -> {
if (!Objects.equals(res.getInteger("code"), 200)) {
@@ -166,7 +176,9 @@ public class UserController {
.retrieve().bodyToMono(JSONObject.class).flatMap(res -> {
if (Objects.equals(res.getInteger("code"), 1) && !res.getString("info")
.contains("该手机号还没有注册哦")) {
- return Mono.just(res);
+ String token = res.getJSONObject("data").getJSONObject("token").getString("token");
+ return reactiveStringRedisTemplate.opsForValue()
+ .set(RedisConstans.IOT_TOKEN.concat(token), token, Duration.ofDays(7)).then(Mono.just(res));
} else if(!res.getString("info").contains("该手机号还没有注册哦")){
return Mono.error(new RuntimeException(res.getString("info")));
}else {
@@ -186,10 +198,14 @@ public class UserController {
object.add("phone", jsonObject.getString("phone"));
object.add("verify", jsonObject.getString("verify"));
return webClient.post().uri(baseUrl + smsUrl).bodyValue(object).retrieve()
- .bodyToMono(JSONObject.class).doOnNext(twoRes -> {
+ .bodyToMono(JSONObject.class).flatMap(twoRes -> {
if (!Objects.equals(twoRes.getInteger("code"), 1)) {
- throw new RuntimeException(twoRes.getString("info"));
+ return Mono.error(new RuntimeException(twoRes.getString("info")));
}
+ String token = res.getJSONObject("data").getJSONObject("token").getString("token");
+ return reactiveStringRedisTemplate.opsForValue()
+ .set(RedisConstans.IOT_TOKEN.concat(token), token, Duration.ofDays(7)).then(Mono.just(res));
+
});
}
});
@@ -205,11 +221,15 @@ public class UserController {
log.info("UserController[]loginByPwd[]jsonObject:{}", jsonObject);
return webClient.post().uri(baseUrl + pwdUrl).bodyValue(getMultiValueMap(jsonObject)).retrieve()
.bodyToMono(JSONObject.class)
- .doOnNext(res -> {
+ .flatMap(res -> {
if (!Objects.equals(res.getInteger("code"), 1)) {
- throw new RuntimeException(res.getString("info"));
+ return Mono.error(new RuntimeException(res.getString("info")));
}
+ String token = res.getJSONObject("data").getJSONObject("token").getString("token");
+ return reactiveStringRedisTemplate.opsForValue()
+ .set(RedisConstans.IOT_TOKEN.concat(token), token, Duration.ofDays(7)).then(Mono.just(res));
});
+
}
private MultiValueMap getMultiValueMap(JSONObject jsonObject) {
diff --git a/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/filter/AuthFilter.java b/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/filter/AuthFilter.java
index 82e29df..ae8d0bd 100644
--- a/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/filter/AuthFilter.java
+++ b/iot-modules/iot-box-user-api/src/main/java/com/qiuguo/iot/user/api/filter/AuthFilter.java
@@ -1,21 +1,9 @@
package com.qiuguo.iot.user.api.filter;
-import com.qiuguo.iot.base.annotation.Auth;
-import com.qiuguo.iot.base.constans.RedisConstans;
-import com.qiuguo.iot.base.constans.UserAuthContains;
-import java.lang.annotation.ElementType;
-import java.time.Duration;
-import java.util.Map;
-import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
-import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.ReactiveStringRedisTemplate;
-import org.springframework.util.ObjectUtils;
-import org.springframework.web.method.HandlerMethod;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
diff --git a/iot-modules/iot-box-user-api/src/main/resources/bootstrap.yml b/iot-modules/iot-box-user-api/src/main/resources/bootstrap.yml
index 5b7a48f..f5cc792 100644
--- a/iot-modules/iot-box-user-api/src/main/resources/bootstrap.yml
+++ b/iot-modules/iot-box-user-api/src/main/resources/bootstrap.yml
@@ -10,10 +10,10 @@ spring:
nacos:
discovery:
# 服务注册地址
- server-addr: 172.24.218.235:8848/
+ server-addr: 192.168.8.146:32470
config:
# 配置中心地址
- server-addr: 172.24.218.235:8848/
+ server-addr: 192.168.8.146:32470
# 配置文件格式
file-extension: yml
# 共享配置
diff --git a/iot-modules/iot-box-user-api/src/test/java/UserTest.java b/iot-modules/iot-box-user-api/src/test/java/UserTest.java
index 59628cf..54ce71d 100644
--- a/iot-modules/iot-box-user-api/src/test/java/UserTest.java
+++ b/iot-modules/iot-box-user-api/src/test/java/UserTest.java
@@ -18,7 +18,7 @@ import org.springframework.boot.test.context.SpringBootTest;
@Slf4j
public class UserTest {
- public String deviceId = "6c4a153095be2b7f8baofp";
+ public String deviceId = "6cae26f5512eee7c12aqd9";
public String spaceId = "163257138";
@@ -88,7 +88,7 @@ public class UserTest {
JSONObject js3 = new JSONObject();
js3.put("code", "bright_value_v2");
js3.put("value", 10);
- commands.put("commands", Arrays.asList( js3));
+ commands.put("commands", Arrays.asList(jsonObject));
Object controlDevice = tuyaDeviceConnector.controlDevice(deviceId,commands);
System.out.println(controlDevice);