问题描述:
我正在使用Angular 7与Spring Boot开发一个项目,并使用h2数据库。我尝试使用JWT进行授权,但是无论如何都无法成功。
解决方法:
下面是一个示例的HttpInterceptor代码:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
intercept(request: HttpRequest, next: HttpHandler): Observable> {
const token = localStorage.getItem('jwtToken'); // 从localStorage中获取JWT令牌
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}` // 添加Authorization头部
}
});
}
return next.handle(request);
}
}
然后,在你的app.module.ts文件中将这个Interceptor添加到providers数组中:
import { JwtInterceptor } from './jwt.interceptor';
@NgModule({
declarations: [
// ...
],
imports: [
// ...
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true } // 添加JwtInterceptor到providers数组中
],
bootstrap: [AppComponent]
})
export class AppModule { }
首先,你需要创建一个自定义的UserDetailsService来获取用户信息。下面是一个示例代码:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
}
}
然后,你需要创建一个自定义的JwtRequestFilter来验证JWT令牌。下面是一个示例代码:
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
最后,在你的SecurityConfig类中配置JWT授权。下面是一个示例代码:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private JwtRequestFilter jwtRequestFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
以上就是使用Angular 7 + Spring Boot + h2数据库进行JWT授权的解决方法。希望对你有帮助!