AngularJS Spring Social Facebook CORS 问题

Posted

技术标签:

【中文标题】AngularJS Spring Social Facebook CORS 问题【英文标题】:AngularJS Spring Social Facebook CORS problem 【发布时间】:2019-05-17 12:44:10 【问题描述】:

我正在尝试使用在不同端口上运行的 AngularJS(1.6) FE 和 Spring Boot(2.1) BE 构建示例登录。我正在使用 Spring Boot Social 启用 FB 登录。

但是当我尝试使用 Facebook 登录时,我得到了这个:

CORS error

我的 FE 是这样的:

<button ng-click="FBLogin()">Facebook Login</button>

然后调用:

$scope.FBLogin = function()
    FB.login(function(response) 
        if (response.status === 'connected') 
            console.log(response);
         else 
            console.log("User cancelled login or did not fully authorize.");
        
    

我的 FE 成功从 Facebook 获取访问令牌。

那么我的BE是这样的:

ActivityController.java

@RestController
@RequestMapping(value = "/act/")
public class ActivityController 
   @Autowired
   ActivityService activityService;

   @RequestMapping(value = "getallactivity")
   @ResponseBody
   public List<Activity> getAllActivity(Principal principal) 
       List<Activity> allActivity = activityService.getAllActivity();
       return allActivity;
   

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@Order(-1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

@Autowired
private UserDetailsService userDetailsService;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception 
    auth.userDetailsService(userDetailsService);


@Override
protected void configure(HttpSecurity http) throws Exception 
    http
    .cors()
    .csrf().disable()
    .authorizeRequests()
    .antMatchers("/", "/signup", "/login**", "/logout", "/auth/facebook")
        .permitAll()
    .antMatchers("/act/**")
        .authenticated()
    .and().formLogin()
      .loginProcessingUrl("/login") // Submit URL
      .loginPage("https://localhost:8444/#!/login")
      .usernameParameter("username")
      .passwordParameter("password");


@Bean
CorsConfigurationSource corsConfigurationSource() 
    System.out.println("CORS BEAN");
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(Arrays.asList("content-type", "accept", "X-Requested-With", "remember-me", "authorization"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;



@Override
public UserDetailsService userDetailsService() 
    return userDetailsService;


编辑1

根据 sideshowbarker 的建议,我也尝试在我的 FE 中启用 CORS。 CORS 错误现已消失,但我在登录后发送给我的 BE 的任何请求都会返回我的 FE 的 index.html

FE 的 WebSecurityConfig.Java

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

@Override
protected void configure(HttpSecurity http) throws Exception 
    http
    .cors()
    .and().authorizeRequests()
    .antMatchers("/**")
        .permitAll()
      .and().formLogin()
      // Submit URL of login page.
    .loginProcessingUrl("https://localhost:8082/login")
    .loginPage("https://localhost:8444/#!/login")
    .defaultSuccessUrl("https://localhost:8444/#!/selectperson")
    .usernameParameter("username")
    .passwordParameter("password");


@Bean
CorsConfigurationSource corsConfigurationSource() 
    System.out.println("CORS BEAN");
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "DELETE", "OPTIONS"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(Arrays.asList("content-type", "accept", "X-Requested-With", "remember-me", "authorization"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;


EDIT2

编辑标题以适应当前问题(之前是 CORS 错误)。此外,我尝试删除 FE 中的 CORS 配置,然后使用 Zuul 代理解决 CORS 错误,同样的事情发生了。 Index.html 总是由任何请求返回。所以我想我的问题在于我的 WebSecurityConfigurerAdapter。我错过了什么吗?

编辑3

解决了最初的问题,因此我将标题恢复为“CORS 问题”并重新添加了 CORS 标记。有兴趣请看答案。

【问题讨论】:

i.stack.imgur.com/9FdJn.png 处的错误消息表明对在端口 8082 上运行的服务器上的路由发出的请求被重定向到在端口 8444 上运行的服务器上的完全不同的登录路由。WebSecurityConfig。问题中的 java 代码似乎适用于在端口 8082 上运行的服务器。您是否还为在端口 8444 上运行的服务器启用了 CORS? 尝试在端口 8444 中启用 CORS。CORS 错误现已消失,但我在登录后发送给我的 BE 的任何请求都会返回我的 FE 的 index.html。请看我的编辑。我尝试使用两个 WebSecurityConfig,但结果始终相同 您可能想要编辑您的问题,以更清楚地了解当前的问题。否则,当前标题和问题的前半部分会产生误导和混淆——因为它们描述了您之前遇到但现在已经解决的问题。 感谢您指出这一点。无论如何,我尝试恢复我的代码 pre Edit1(FE 中没有 CORS 配置)并实施 Zuul 代理来解决 CORS 错误,并且发生了同样的事情。 Index.html 总是被任何请求返回 【参考方案1】:

好的,所以我想出了一个解决这个问题的方法。我认为 Facebook javascript SDK 的 FBLogin 函数与我当前的 Spring Social 实现不匹配。即使成功登录 FB 也无法授权用户,因此由于此代码,我的后端尝试将我重定向回前端的登录页面(没有 CORS 实现):

http.
.loginPage("https://localhost:8444/#!/login")

所以我没有使用 FBLogin 函数,而是将我的页面直接重定向到 /auth/facebook,就像这样

    $scope.login = function()
        $window.location.href = 'https://localhost:8082/auth/facebook';
    

【讨论】:

以上是关于AngularJS Spring Social Facebook CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

spring social facebook + api + angularjs(如何从 angular 调用 -> spring api -> 重定向到 facebook 登录)

Spring Social Login:如何添加同一个社交提供商(例如 Facebook)的多个应用程序?

使用带有struts2的spring social

spring官方为什么放弃spring social项目及替代方案

019 spring social

Grails - Spring Security / Social - Facebook 插件 setAccessToken 和 getAccessToken