2016-12-26 50 views
1

我被我的项目卡住了交叉原点cors问题。我必须将运行在localhost:4200上的Angular2应用程序的获取请求发送到在本地主机:8080上运行的具有一些标头属性的Spring Boot后端。我想要发送的请求看起来像这样:angular2 spring boot cross-origin cors

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') 
     ); 


} 

但是这个请求没有到达服务器端如何我想要它。用邮差来测试api是否有效。

我的春天引导后端是这样的:

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(); 

}... 

我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() { 
    } 

} 

威特邮差它正常工作:

Postman Get Request

但是当我测试它在我的chrome浏览器,我得到:

Chrome Request

所以对我来说,它看起来像我不会在我的后端接收到类似“授权”头的性能。我也通过在spring引导后端调试请求来看到这一点。我只是看到“null”作为这个请求的头部。

有没有人有一个想法,为什么我没有得到我的请求头在API端点正确?

我已经有了一看这里:

restlet.com/blog/2016/09/27/how-to-fix-cors-problems/

,看着张贴在计算器几个类似的问题。

+0

你有没有试图改变'“访问控制允许来源”,“HTTP://本地主机:4200”'以“Access-Control-Allow-Origin”,“*”' – Alex

+1

它适用于以下解决方案: 将此添加到弹簧安全配置中: .antMatchers(org.springframework.http.HttpMethod.OPTIONS,“/ service/** “).permitAll() http://stackoverflow.com/questions/36142155/cors-origin-spring-boot-jhipster?rq=1 – Tobi

+0

蚂蚁感谢您的意见。是的,我也用''Access-Control-Allow-Origin','*'''试过了, – Tobi

回答

2

对我来说它的工作原理与此解决方案: 添加这个春天的安全配置:

.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令牌仍然需要,我多么想拥有它)

来自:

CORS Origin Spring Boot Jhipster - pre-flight fails

+0

腰了4个小时,认为我的标题不正确。即使启用了CROS,也没有工作。 .antMatchers(org.springframework.http.HttpMethod.OPTIONS,“/ service/**”)工作,但为什么这仍然需要JWT授权,即使我们已经设置。 permitALL()? – Gauranga

0

我有这个相同的问题,我使用春季启动为我的API和角2.3.1。我不确定你是否使用Npm和Angular Cli。如果您使用npm进行开发,那么可以采取以下措施来解决此问题。您可以将api调用代理到您的后端。

第1步:在包的同一目录下创建一个名为proxy.conf.json的文件。JSON具有以下内容

{ 
    "/api": { 
    "target": "http://localhost:8080", 
    "secure": false, 
    "pathRewrite": {"^/api" : ""} 
    } 
} 

这样,而不是使用http://localhost:8080/service/events/byTeamId/1的API请求,您将使用/api/service/events/byTeamId/1

注意添加“/ API”和消除“http://localhost:8080”。这意味着任何以/ api开头的请求都将被代理。这是你想要的,因为你不只是想要任何网址被代理。该行 "pathRewrite": {"^/api" : ""} 确保“/ api”被删除,以便最终您的实际url被请求。

步骤2:更新的package.json

更新行 "start": "ng serve", 并将它更改为 "start": "ng serve --proxy-config proxy.conf.json", 这将确保该代理被配置并用于

步骤3:使用NPM开始

虽然使用角度cli,并确保您在项目直接ORY您现在可以开始您的应用程序在您的请求代理使用

npm start 

Angular Cli documentation