httpOnly在rest api(Sping Boot )和VueJS之间的cookie

qacovj5a  于 2022-11-17  发布在  Vue.js
关注(0)|答案(1)|浏览(130)

我正在实现Sping Boot API和VueJS。实际上,当我将JWT存储到本地存储时,一切都正常。
现在互联网上有很多文章说“不要将jwt存储在本地存储中,将其存储为httpOnly cookie以避免XSS攻击”
现在我正在尝试这样做,但是在创建httpOnly cookie之后,下一个请求不包含cookie。
在本地主机8080上运行的Sping Boot 和在本地主机8081上运行的VueJ
安全配置:

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    ...

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowedOrigins(List.of("http://localhost:8081", "http://localhost:8082"));
        corsConfiguration.setAllowedMethods(Collections.singletonList(CorsConfiguration.ALL));
        corsConfiguration.setAllowedHeaders(Collections.singletonList(CorsConfiguration.ALL));
        corsConfiguration.setMaxAge(Duration.ofMinutes(10));
        corsConfiguration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(source);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();

        http.cors().and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                ...
    }
}

在登入端点中:

@RestController
@RequestMapping("/api")
public class LoginController {
    ...

    @PostMapping("/login")
    public ResponseEntity<?> doLogin(@RequestBody @Valid MyRequest loginRequest, HttpServletResponse response) {
        String jwt = loginService.doLogin(loginRequest);
        ResponseCookie cookie = ResponseCookie.from("my-http-only-cookie", jwt)
                .path("/")
                .httpOnly(true)
                .build();

        return ResponseEntity
                .ok()
                .header(HttpHeaders.SET_COOKIE, cookie.toString())
                .body(jwt);
    }
}

现在,如果我从vuews(8081)发送登录请求,我可以看到set-cookies响应:

Set-Cookie: my-http-only-cookie=eyJhbGciOiJIUzUxMiJ9.e...; Path=/; HttpOnly;

但是下面的 AJAX 请求不包含名为my-http-only-cookie的cookie,我可以在我的OncePerRequestFilter中验证这一点:

public class MyFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        for (Cookie eachCookie : request.getCookies()) {
            logger.info("Cookie name: {} and value: {}", eachCookie.getName(), eachCookie.getValue());
        }
        filterChain.doFilter(request, response);
    }

    ...
}

同样在VueJs应用程序中,我发送 AJAX 请求:

testRequest(jwt) {
    return axios.post("/...", ... , {
      headers: {
        Authorization: "Bearer " + jwt,
      },
      withCredentials: true,
    });
  }

据我所知,cookie是不共享不同的域,如localhost:8080和localhost:8081。那么我如何才能实现最安全的httpOnly jwt cookie?

7kjnsjlb

7kjnsjlb1#

您只需要创建带有“localhost”但没有端口的cookie,就可以在localhost:8080和localhost:8081之间共享它,例如:

public static void createWithHttpOnly(HttpServletResponse httpServletResponse, String token) {
  javax.servlet.http.Cookie.Cookie cookie = new Cookie("my-http-only-cookie", token);
  cookie.setSecure(true);
  cookie.setHttpOnly(true);
  cookie.setMaxAge(-1);
  cookie.setDomain("localhost");
  cookie.setPath("/");
  httpServletResponse.addCookie(cookie);
}

相关问题