angular2弹簧靴交叉起源的角

时间:2016-12-26 16:21:53

标签: angular spring-boot cors

我遇到了与我的项目交叉起源的问题。我必须从运行在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它运作正常:

Postman Get Request

但是当我在Chrome浏览器上测试时,我得到了:

Chrome Request

所以对我来说,我的后端看起来没有像“授权”那样收到标题属性。我也通过在spring boot后端调试请求来看到这一点。我只看到“null”作为此请求的标题。

有没有人知道为什么我的api端点没有正确的请求标头?

我已经看过这里了:

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

并查看了stackoverflow上发布的几个类似问题。

2 个答案:

答案 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令牌,我希望如何拥有它)

从:

CORS Origin Spring Boot Jhipster - pre-flight fails

答案 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

Angular Cli documentation