我遇到了与我的项目交叉起源的问题。我必须从运行在localhost:4200上的Angular2应用程序发送一个get请求到我在Springhost:8080上运行的Spring Boot后端,并带有一些头属性。我想发送的请求如下:
test() {
let jwt = localStorage.getItem('token');
let headers = new Headers({
'Content-Type': 'application/json; charset=utf-8',
'Authorization': 'Bearer ' + jwt
});
let options = new RequestOptions({ headers: headers });
this.http.get('http://localhost:8080/service/events/byTeamId/1', options)
.map((response: Response) => response.json())
.subscribe(
data => console.log('Response: '+data),
err => console.log('error: '+err),
() => console.log('Secret Quote Complete')
);
}
但是这个请求并没有到达服务器端我是怎么想拥有它的。随着Postman测试api它的工作原理。
My Spring Boot后端看起来像这样:
WebSecurityConfig.java:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Autowired
private SimpleCorsFilter simpleCorsFilter;
@Resource
private UserDetailsServiceImpl userDetailsService;
@Resource
private JwtAuthenticationProvider jwtAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "/login", "/register").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(simpleCorsFilter, ChannelProcessingFilter.class)
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.logout()
.permitAll()
.and().csrf().disable();
}...
My SimpleCorsFilter看起来像这样:
@Component
public class SimpleCorsFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCorsFilter.class);
public SimpleCorsFilter() {
log.info("SimpleCORSFilter init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200");
//response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
Wit Postman它运作正常:
但是当我在Chrome浏览器上测试时,我得到了:
所以对我来说,我的后端看起来没有像“授权”那样收到标题属性。我也通过在spring boot后端调试请求来看到这一点。我只看到“null”作为此请求的标题。
有没有人知道为什么我的api端点没有正确的请求标头?
我已经看过这里了:
restlet.com/blog/2016/09/27/how-to-fix-cors-problems /
并查看了stackoverflow上发布的几个类似问题。
答案 0 :(得分:2)
对我而言,它适用于此解决方案: 将此添加到spring security config:
.antMatchers(org.springframework.http.HttpMethod.OPTIONS, "/service/**").permitAll()
http
.authorizeRequests()
.antMatchers("/", "/home", "/login", "/register").permitAll()
.antMatchers(org.springframework.http.HttpMethod.OPTIONS, "/service/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(simpleCorsFilter, ChannelProcessingFilter.class)
.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.logout()
.permitAll()
.and().csrf().disable();
(仍然需要jwt令牌,我希望如何拥有它)
从:
答案 1 :(得分:0)
我遇到了同样的问题,我正在为我的api和 Angular 2.3.1 使用spring boot。我不确定你是否使用Npm和Angular Cli。如果您使用npm进行开发,则可以执行以下操作来解决此问题。您可以将api调用代理到您的后端。
步骤1:在与package.json相同的目录中创建一个名为proxy.conf.json 的文件,其中包含以下内容
{
"/api": {
"target": "http://localhost:8080",
"secure": false,
"pathRewrite": {"^/api" : ""}
}
}
因此,您可以使用http://localhost:8080/service/events/byTeamId/1
/api/service/events/byTeamId/1
来处理您的api请求
注意添加的“/ api”和删除“http://localhost:8080”。这意味着任何以/ api开头的请求都将被代理。这就是你想要的,因为你不只是想要代理任何url。这条线
"pathRewrite": {"^/api" : ""}
确保删除“/ api”,以便最终请求您的实际网址。
第2步:更新package.json
更新该行
"start": "ng serve",
并将其更改为
"start": "ng serve --proxy-config proxy.conf.json",
这将确保配置和使用代理
第3步:使用npm start
使用angular cli并确保您在项目目录中时,您现在可以使用
启动您的请求代理请求npm start