如何将Vaadin作为前端微服务与Spring REST API后端微服务集成
实现Vaadin Flow微服务对接JWT鉴权Spring Boot后端方案
以下是可直接落地的实现逻辑和核心代码:
整体实现流程
- 开发Vaadin侧登录视图,收集用户输入的用户名、密码
- 调用Spring Boot后端公开的登录接口获取JWT令牌,将令牌存入Vaadin会话存储
- 配置全局请求拦截逻辑,所有发往后端的API请求自动在请求头中追加
Authorization: Bearer <令牌> - 配置Vaadin侧路由访问控制,未登录用户禁止访问仪表盘等受保护路由
核心代码实现
1. Vaadin侧登录认证服务
@Service public class AuthService { private final RestTemplate restTemplate; private final VaadinSession vaadinSession; // 构造函数注入依赖 public AuthService(RestTemplate restTemplate, VaadinSession vaadinSession) { this.restTemplate = restTemplate; this.vaadinSession = vaadinSession; } public boolean login(String username, String password) { // 构造登录请求参数 Map<String, String> loginRequest = Map.of( "username", username, "password", password ); try { ResponseEntity<Map> response = restTemplate.postForEntity( "http://你的Spring后端服务地址/api/auth/login", loginRequest, Map.class ); // 提取JWT令牌存入当前会话 String jwt = (String) response.getBody().get("token"); vaadinSession.setAttribute("jwt_token", jwt); vaadinSession.setAttribute("current_username", username); return true; } catch (HttpClientErrorException e) { // 用户名密码错误等异常场景处理 return false; } } // 获取当前登录用户的JWT令牌 public String getCurrentJwt() { return (String) vaadinSession.getAttribute("jwt_token"); } // 校验当前用户登录状态 public boolean isAuthenticated() { return getCurrentJwt() != null; } // 登出逻辑:清除会话存储的令牌 public void logout() { vaadinSession.removeAttribute("jwt_token"); vaadinSession.close(); } }
2. 全局请求拦截配置(自动追加Bearer令牌)
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); // 配置拦截器自动注入JWT到请求头 restTemplate.setInterceptors(List.of((request, body, execution) -> { VaadinSession currentSession = VaadinSession.getCurrent(); if (currentSession != null) { String jwt = (String) currentSession.getAttribute("jwt_token"); if (jwt != null) { request.getHeaders().setBearerAuth(jwt); } } return execution.execute(request, body); })); return restTemplate; } }
3. 路由访问控制配置
@Component public class AuthNavigationInterceptor implements BeforeEnterObserver { private final AuthService authService; public AuthNavigationInterceptor(AuthService authService) { this.authService = authService; } @Override public void beforeEnter(BeforeEnterEvent event) { // 登录页公开可访问,无需鉴权 boolean isLoginRoute = event.getNavigationTarget().equals(LoginView.class); if (isLoginRoute) { // 已登录用户访问登录页直接跳转仪表盘 if (authService.isAuthenticated()) { event.rerouteTo(DashboardView.class); } return; } // 未登录用户访问受保护路由直接跳转登录页 if (!authService.isAuthenticated()) { event.rerouteTo(LoginView.class); } } }
注意事项
- 后端登录接口必须排除在JWT拦截规则之外,否则未登录用户无法调用登录接口获取令牌
- JWT默认随Vaadin会话过期自动失效,无需额外维护本地缓存生命周期
- 如果需要实现跨标签页登录状态同步,可以将加密后的JWT存入浏览器Cookie,会话初始化时自动读取校验
内容的提问来源于stack exchange,提问作者Techguy
相关产品推荐
相关产品推荐

