Flutter无法向SSL加密的SpringBoot后端发送请求求助
问题排查:Flutter前端无法向带SSL和Spring Security的Spring Boot后端发送请求
我正在开发Android平台的Flutter前端,后端是配置了本地SSL加密和Spring Boot Security的Spring Boot服务。现在前端向后端发送请求时,本地服务器完全接收不到请求。
Flutter请求发送代码
import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:flutter/rendering.dart'; import 'package:http/http.dart' as http; import 'package:test_flutter/enpoints.dart'; class ApiService { Future register(String username, String password) async { try { Uri url = Uri.parse(Endpoints.register); print(url); var response = await http.post(url, body: {"email": username, "password": password}); print(response.body); if (response.statusCode == 200) { print(response.body); return response.body; } } catch (e) { log(e.toString()); } } }
Spring Boot Security配置代码
@EnableWebSecurity public class SecurityConfigurations { @Autowired private JWTAuthenticationFilter jwtAuthenticationFilter; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain configureHttpSecurity(HttpSecurity httpSecurity) throws Exception { httpSecurity.authorizeRequests().antMatchers("/authentication/**", "/public/**") .permitAll(); httpSecurity.authorizeRequests().antMatchers("/api/**").authenticated(); httpSecurity.formLogin().disable(); httpSecurity.httpBasic().disable(); httpSecurity.csrf().disable(); httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); httpSecurity.cors().configurationSource(corsConfigSource()); httpSecurity.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return httpSecurity.build(); } @Bean public UrlBasedCorsConfigurationSource corsConfigSource() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); return source; } }
SSL配置(application.properties)
server.port=8080 server.ssl.enabled=true server.ssl.key-alias=local_ssl server.ssl.key-store-password=keystore server.ssl.key-password=keystore server.ssl.key-store-type=PKCS12 server.ssl.key-store=classpath:local-ssl.p12
测试验证情况
搭建无SSL、无Spring Boot Security的全新Spring Boot应用并暴露/test接口时,Flutter可正常发送请求并接收响应。使用Mac设备,已尝试在真机和模拟器运行Flutter,且Mac防火墙已关闭。
推测的问题点
- Flutter代码错误(如请求头不正确、URL错误)
- Spring Boot Security配置不当
- SSL相关问题
- Mac系统因SSL证书拦截请求
排查方案
1. 优先排查SSL证书问题(最可能原因)
Flutter默认拒绝自签名SSL证书,这会导致请求根本无法建立连接,服务器自然接收不到请求。
- 临时开发绕过(仅用于测试):在Flutter的
main函数中添加以下代码,跳过SSL证书验证:
测试如果请求能正常发送,说明就是SSL证书信任问题。import 'dart:io'; class MyHttpOverrides extends HttpOverrides { @override HttpClient createHttpClient(SecurityContext? context) { return super.createHttpClient(context) ..badCertificateCallback = (X509Certificate cert, String host, int port) => true; } } void main() { HttpOverrides.global = MyHttpOverrides(); runApp(MyApp()); } - 正式处理方式:将本地SSL证书转换为PEM格式,放入Flutter项目的
assets/certs目录,然后在请求时配置信任该证书:SecurityContext context = SecurityContext.defaultContext; context.setTrustedCertificates('assets/certs/local-ssl.pem'); HttpClient client = HttpClient(context: context); // 使用该client发送请求,或封装到http包的Client中
2. 检查Flutter请求的URL正确性
- 确认
Endpoints.register的URL是https开头(后端启用了SSL,必须用HTTPS协议),比如https://localhost:8080/authentication/register,如果写的是http,请求会直接失败。 - 查看Flutter控制台的
print(url)输出,确认URL路径是否匹配Spring Boot中开放的/authentication/**或/public/**范围,如果路径是/api/register,会被Security拦截要求认证(但这种情况服务器会返回401,而非接收不到请求)。 - 查看catch块中的
log(e.toString())输出,是否有SSL握手失败、连接超时等异常信息,这能直接定位问题。
3. 验证Spring Boot后端的可用性
在Mac终端用curl测试后端接口,确认后端本身能正常响应:
curl -k https://localhost:8080/你的注册接口路径 -d "email=test&password=123"
- 如果curl能收到响应,说明后端没问题,问题在Flutter端;
- 如果curl也失败,检查Spring Boot的SSL配置是否正确,比如证书文件是否正确放置在classpath下,密码是否匹配。
4. 检查Spring Security和CORS配置
- 确认JWT过滤器是否会拦截未认证的请求:如果你的注册接口属于
/authentication/**,但JWT过滤器在UsernamePasswordAuthenticationFilter之前执行,是否会提前拦截请求?可以临时注释掉addFilterBefore代码,测试请求是否能到达服务器。 - CORS配置中,
config.setAllowCredentials(true)与config.addAllowedOrigin("*")在部分场景下存在冲突,可尝试将允许的origin改为具体的Flutter地址(比如http://localhost:5000,根据你的Flutter运行端口调整),测试是否能解决问题。
内容的提问来源于stack exchange,提问作者Seema Sharma
相关产品推荐
相关产品推荐

