SpringBoot-前后端分离

笔记参考与柏码知识库

基于Session分离

使用Cookie中的JSESSIONID数据。

登录授权和跨域处理

前后端分离后,后端只需返回前端数据,不需要进行重定向,可以手动设置SuccessHandler和FailureHandler来实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
...
.formLogin(conf -> {
conf.loginProcessingUrl("/api/auth/login");
//使用自定义的成功失败处理器
conf.failureHandler(this::onAuthenticationFailure);
conf.successHandler(this::onAuthenticationSuccess);
conf.permitAll();
})
...
}

//自定义成功失败处理器
void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) {

}

void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) {

}

返回的JSON推荐使用Rest API标志进行编写。

创建实体类装载响应数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public record RestBean<T> (int code, T data, String message) {
//写几个工具方法,用于快速创建RestBean对象
public static <T> RestBean<T> success(T data){
return new RestBean<>(200, data, "请求成功");
}

public static <T> RestBean<T> failure(int code, String message){
return new RestBean<>(code, null, message);
}

public static <T> RestBean<T> failure(int code){
return failure(code, "请求失败");
}
//将当前对象转换为JSON格式的字符串用于返回
public String asJsonString() {
return JSONObject.toJSONString(this, JSONWriter.Feature.WriteNulls);
}
}

设置Handler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException exception) throws IOException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(RestBean.failure(401, exception.getMessage()).asJsonString());
}

void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(RestBean.success(authentication.getName()).asJsonString());
}

跨域配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
...
.cors(conf -> {
CorsConfiguration cors = new CorsConfiguration();
//添加前端站点地址,这样就可以告诉浏览器信任了
cors.addAllowedOrigin("http://localhost:8080");
//虽然也可以像这样允许所有 cors.addAllowedOriginPattern("*");
//但是这样并不安全,我们应该只许可给我们信任的站点
cors.setAllowCredentials(true); //允许跨域请求中携带Cookie
cors.addAllowedHeader("*"); //其他的也可以配置,为了方便这里就 * 了
cors.addAllowedMethod("*");
cors.addExposedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", cors); //直接针对于所有地址生效
conf.configurationSource(source);
})
...
.build();
}