拥有这个简单的反应客户端:
import axios from 'axios';
import { useEffect, useState } from 'react';
// token generated from the backend (via JwtService)
const token = 'eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKYW5lIiwiaWF0IjoxNzAxODIyODYxLCJleHAiOjE3MDE4MjQ2NjF9.QxF5B3SdnMNXILokaFkfebcYQfiAToefFHaCqF-zh_c';
function App() {
const [users, setUsers] = useState([]);
useEffect(() => {
axios.get("http://localhost:8080/users", {
headers: {
Authorization: `Bearer ${token}`
}
}).then(res => {
setUsers(res.data)
})
})
return (
<ul>
{users.map(u => (
<li key={u.id}>{u.username}</li>
))}
</ul>
);
}
export default App;
和 Spring Boot 后端:
UserController.java:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping()
public ResponseEntity<List<UserDtoout>> getUsers(){
return ResponseEntity.ok(userService.getAllUsers());
}
}
JwtAuthFilter.java:
@Component
public class JwtAuthFilter extends OncePerRequestFilter {
@Autowired
private JwtService jwtService;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String username = null;
String token = null;
String authHeader = request.getHeader("Authorization");
if(authHeader != null && authHeader.startsWith("Bearer ")) {
token = authHeader.substring(7);
username = jwtService.extractUsername(token);
}
if(username != null && SecurityContextHolder.getContext().getAuthentication() == null){
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if(jwtService.validateToken(token, userDetails.getUsername())) {
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
}
}
SecurityConfig.java:
@Configuration
public class SecurityConfig implements WebMvcConfigurer {
@Autowired
private JwtAuthFilter authFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.cors(Customizer.withDefaults())
.authorizeHttpRequests(req -> req
.requestMatchers("/register").permitAll()
.requestMatchers("/login").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider());
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
UserDetailsService userDetailsService() {
return new UserDetailsServiceImpl();
}
@Bean
public AuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService());
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
return configuration.getAuthenticationManager();
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000");
}
}
我从 axios 获取
403
状态代码。在 insomia(http 客户端,如邮递员)中使用 get 方法发送请求并硬编码 Authorization: Bearer ...
作为标头后,请求完成并获取用户。在检查了反应浏览器中的控制台后,我没有在请求标头中看到授权标头,所以看起来该标头根本没有发送。
使用 Content-Type 标头。
headers: {
'Content-Type': 'application/json'
}
并且您应该使用
Post
而不是 GET
。
https://stackoverflow.com/a/29574160/17630977