Spring Security 如何修复使用SSE连接EventSource时出现的错误403?

svmlkihl  于 2023-08-05  发布在  Spring
关注(0)|答案(1)|浏览(303)

后端:Spring安全JWT,

@CrossOrigin(origins = "http://localhost:4444", allowCredentials = "true")
    @GetMapping("/")
    public Flux<ServerSentEvent<List<UserResponse>>> getAll() throws CancelQueryException {
        return Flux.interval(Duration.ofSeconds(3))
                .flatMap(sequence -> {
                    List<UserResponse> data = null;
                    try {
                        data = userService.getAllUsers();
                        System.out.println("data: " + data);
                    } catch (CancelQueryException e) {
                        //   LOGGER.error("Error occurred while retrieving users", e);
                        throw new RuntimeException(e);
                    }
                    return Mono.just(ServerSentEvent.<List<UserResponse>>builder()
                            .id(String.valueOf(sequence))
                            .event("update")
                            .data(data)
                            .build());
                });
    }

字符串
前端:React

useEffect(() => {
    const token =
      "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJld2ZhZXJnZSIsImlhdCI6MTY4ODEwNTg4MCwiZXhwIjoxNjg4NzEwNjgwfQ.V3d_1n7QElQZpPshH_UkkR707sLJlxqz7fYmqSJ3V-4";
    const config = {
      withCredentials: true,
      headers: {
        Authorization: `Bearer ${token}`,
      },
    };
    const url = "http://localhost:8558/monitoring-location/api/v1/admin/user/";
    try {
      const eventSource = new EventSource(url, config);

      eventSource.onmessage = (event) => {
        const receivedEvent = JSON.parse(event.data);
        console.log(receivedEvent);
      };
      console.log("running");

      return () => {
        console.log("close connecttion");
        eventSource.close(); // Đóng kết nối SSE khi component bị hủy
      };
    } catch (error) {
      console.log("error ----", error);
    }
  }, []);


令牌正确,但响应为ERROR 403
请帮帮我,谢谢
我正在使用SSE协议从服务器向FE发送数据,但收到错误403

kqlmhetl

kqlmhetl1#

const eventSource = new EventSource(url, config);中,唯一可以进入config的是withCredentials
因此,您添加的headers:{...}将被忽略。
根据https://stackoverflow.com/a/36226251/841830(我,7年前),您需要使用cookie进行身份验证。
然而,从https://stackoverflow.com/a/31958864/841830(链接到https://www.rfc-editor.org/rfc/rfc6750)听起来你也可以在URL本身中放置一个Bearer令牌。而且,事实上,上述问题的另一个答案说,这就是他们最终所做的,然后依靠SSL来保证安全。
但那不是100%安全的,所以你需要自己做风险评估;上述RFC的第5节说:
不要在页面URL中传递不记名令牌:不应该在页面URL中传递承载令牌(例如,作为查询字符串参数)。相反,承载令牌应该在采取保密措施的HTTP消息头或消息体中传递。浏览器、web服务器和其他软件可能无法充分保护浏览器历史记录、web服务器日志和其他数据结构中的URL。如果在页面URL中传递不记名令牌,攻击者可能能够从历史数据、日志或其他不安全位置窃取它们。

相关问题