无需调用findByUsername获取User实体name字段的优化方案咨询
无需额外查询获取User的name字段优化方案
你当前在登录验证后额外执行了一次findUserByUsername数据库查询,这完全没必要——Spring Security的Authentication对象里的Principal就是你自定义的SecurityUser实例,而它本身已经持有完整的User实体,直接从中提取即可。
优化步骤
- 从
Authentication对象中取出Principal,强转为SecurityUser类型 - 通过
SecurityUser获取内部的User对象,直接拿到name字段(需要给SecurityUser新增一个暴露内部User的方法)
修改后的代码
AuthenticationController.java
@PostMapping("/login") public ResponseEntity<AuthenticationResponse> login (@RequestBody AuthenticationRequest userLogin) { try { Authentication authentication = authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(userLogin.username(), userLogin.password())); String token = tokenService.generateToken(authentication); // 直接从Principal获取SecurityUser,跳过额外数据库查询 SecurityUser securityUser = (SecurityUser) authentication.getPrincipal(); String userName = securityUser.getUser().getName(); AuthenticationResponse response = new AuthenticationResponse(userName, token); return ResponseEntity.ok().body(response); } catch (BadCredentialsException e) { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); } }
SecurityUser.java(新增getUser方法)
public class SecurityUser implements UserDetails { private final User user; public SecurityUser (User user) { this.user = user; } // 新增方法,暴露内部User对象 public User getUser() { return user; } @Override public String getUsername() { return user.getUsername(); } @Override public String getPassword() { return user.getPassword(); } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return user .getRoles() .stream() .map(role -> new SimpleGrantedAuthority(role.getName())) .collect(Collectors.toSet()); } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } @Override public String toString() { return "SecurityUser{" + "user=" + user + '}'; } }
内容的提问来源于stack exchange,提问作者Othmane
相关产品推荐
相关产品推荐

