SpringBook + VueJS + SpringSecurity Cookie is not passed



我正在使用 SpringBoot2 和 VueJS 创建一个项目。我正在使用自定义 JWT 令牌进行授权。当用户登录时,我在响应"AUTH_TOKEN=tokenValue"中设置了一个cookie。我预计来自 VueJS 的每个调用(使用fetch(都会将该 cookie 传递给 SpringBoot,但并非所有端点都会获得 cookie。

当我使用 RestTemplate 和 Postman 测试 SpringBoot 时,cookie 传递得很好,端点可以正常工作。当我使用 VueJS 网站时,cookie 只会传递给在我的 SecurityConfig 中有"permitAll"的端点。

我还验证了我的 VueJS 总是在发送 cookie(我使用 php 端点来测试这一点,并且 cookie 总是在那里(。因此,当我使用浏览器并且并非所有端点都有cookie时,会发生一些事情。这是我的配置以及我如何使用它:

安全配置:

@Configuration
open class SecurityConfig(private val jwtTokenProvider :JwtTokenProvider) : WebSecurityConfigurerAdapter() {

@Bean
override fun authenticationManagerBean(): AuthenticationManager {
return super.authenticationManagerBean()
}
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
//@formatter:off
http
.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/thisEndpointDoesGetTheCookie").permitAll()
.anyRequest().authenticated() //Anything else does not
.and()
.apply(JwtConfigurer(jwtTokenProvider))
//@formatter:on
}
}

当我使用permitAll设置另一个端点时,该端点也开始获取令牌(在我的 jwt配置器/提供程序中(

调用是使用fetch和 VueJS 完成

的这是我的注销示例(与任何其他端点相同(

logout() {
fetch('http://localhost:8100/auth/logout', {
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
,credentials: 'include', //Yes I'm including the credentials
body: ""
}).then(res => {
console.log("Logout was successful");
}).catch(error => {
console.log(error.message);
console.log("Logout failed");
});
},

这就是我在用户登录时设置 cookie 的方式。我可以在浏览器中看到它

// create a cookie
val cookie = Cookie("AUTH_TOKEN", signedInUser.token)
// expires in 30 days
cookie.maxAge = 30 * 24 * 60 * 60
// optional properties
cookie.secure = authTokenCookieSecure //false for localhost
cookie.isHttpOnly = true
cookie.path = "/"
// add cookie to response
response.addCookie(cookie)

当我使用 TestRestTemplate(从我的测试中(进行调用时或使用 邮递员 端点的行为符合预期。

val headers = HttpHeaders()
headers["Cookie"] = "AUTH_TOKEN=$jwtToken"

我错过了什么?

出现问题是因为您必须在 Spring 安全性中配置 CORS。 对于自定义标头,您必须在 Access-Control-Expose-Headers 中设置标头名称。

示例解决方案代码:

@Bean
fun corsConfigurationSource(): CorsConfigurationSource {
val configuration = CorsConfiguration().applyPermitDefaultValues()
configuration.allowedOrigins = listOf("*")
configuration.allowedMethods = HttpMethod.values().map { it.name }
configuration.allowedHeaders = listOf("*")
configuration.exposedHeaders = listOf("AUTH_TOKEN")
val source = UrlBasedCorsConfigurationSource()
source.registerCorsConfiguration("/**", configuration)
return source
}

此 CORS 配置允许任何域访问标头。这是 DEV 环境的良好解决方案。对于 PROD,应指定原产地,而不是提供 *。

友情链接: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

相关内容

最新更新