Angular 6 Http拦截器,未修改请求标头 [英] Angular 6 Http Interceptors, request headers not modified
问题描述
我创建了一个拦截器,向客户端发送的每个请求添加一个授权标头,这是代码:
I created an interceptor to add an authorization header to each request sent by the client, here is the code :
import { HttpInterceptor, HttpRequest, HttpHandler, HttpHeaderResponse, HttpSentEvent, HttpProgressEvent, HttpResponse, HttpUserEvent, HttpEvent, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";
import { Injectable } from "@angular/core";
@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(localStorage.getItem('jwtToken'));
if(localStorage.getItem('jwtToken')){
const request = req.clone({
setHeaders: {
Authorization: `bearer ${localStorage.getItem('jwtToken')}`
}
});
console.log(request.headers.get("Authorization"));
return next.handle(request);
}
return next.handle(req);
}
}
发送请求时,将调用函数拦截,并使用变量"request"中的令牌值正确设置授权标头,如您所见: 令牌控制台屏幕截图
When a request is sent the function intercept is called and the authorization header is correclty set with the token value in the variable "request" as you can see there : token console screenshot
但是授权标头未出现在我的浏览器发送的请求中:网络请求标头,后端无法解析令牌.
But the authorization header doesn't appear in the request sent by my browser : network request headers and the backend cannot resolve the token.
你知道为什么吗?
这是我的弹簧配置:
WebSecurityConfig.java
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public final static String AUTHORIZATION_HEADER = "Authorization";
@Autowired
UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(getProvider());
}
@Bean
public JwtTokenFilter jwtAuthenticationFilter() {
return new JwtTokenFilter();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/auth/**")
.permitAll()
.anyRequest()
.authenticated();
}
@Bean
public AuthenticationProvider getProvider() {
AppAuthProvider provider = new AppAuthProvider();
provider.setUserDetailsService(userService);
return provider;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
CorsConfig.java
CorsConfig.java
@Configuration
public class CorsConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("*")
.allowedHeaders("*");
}
};
}
}
推荐答案
您的问题出在后端服务中.出于安全原因,默认情况下仅接受某些标头,而其他标头将被忽略.
Your problem resides into backend services. For security reasons by default only some headers are accepted, the others are ignored.
要解决您的问题,您需要设置自定义接受的标题. Authorization
标头,即使就像JWT的标准一样,也被视为自定义标头.
To fix your problem you need to setup custom accepted headers. Authorization
header, even if is like a standard for JWT, is considered a custom header.
我可以举一个我的Spring Security配置示例:
I can give you an example of my Spring Security configuration:
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
注意该行
config.addAllowedHeader("*");
这意味着我的REST服务接受客户端发送的所有可能的标头. 显然,这不是一个很好的配置,应限制所允许的标头和其他内容以使其符合您的需求.
That means that my REST services accept all possible headers sent by the client. Obviously it's not a good configuration, you should limit allowed headers and other things to match your needs, as restricted as is possible.
很明显,如果您不使用Spring Security,则需要找到使用您的语言/框架进行相同操作的方法.
Obviously if you don't use Spring Security you need to find the way to do the same thing with yout language/framework.
这是我的SecurityConfig.java.与您的有点不同. 试试这个,让我知道
This is my SecurityConfig.java It's a bit different from yours. Try this and let me know
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Autowired
private WLUserDetailsService userDetailsService;
@Value("${jwt.header}")
private String tokenHeader;
@Value("${jwt.route.authentication.path}")
private String authenticationPath;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoderBean());
}
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// we don't need CSRF because our token is invulnerable
.csrf().disable()
// TODO adjust CORS management
.cors().and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// don't create session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated();
// Custom JWT based security filter
JwtAuthorizationTokenFilter authenticationTokenFilter = new JwtAuthorizationTokenFilter(userDetailsService(), jwtTokenUtil, tokenHeader);
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// // disable page caching
// httpSecurity
// .headers()
// .frameOptions().sameOrigin() // required to set for H2 else H2 Console will be blank.
// .cacheControl();
}
@Override
public void configure(WebSecurity web) {
// AuthenticationTokenFilter will ignore the below paths
web
.ignoring()
.antMatchers(
HttpMethod.POST,
authenticationPath
)
// allow anonymous resource requests
.and()
.ignoring()
.antMatchers(
HttpMethod.GET,
"/",
"/*.html",
"/favicon.ico",
"/**/*.html",
"/**/*.css",
"/**/*.js"
);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
// config.addExposedHeader("Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
// "Content-Type, Access-Control-Request-Method, Custom-Filter-Header");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
这篇关于Angular 6 Http拦截器,未修改请求标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!