Клиент Spring Boot oAuth2 с угловой проблемой CORS

Я пытаюсь настроить вход в социальную сеть Facebook в своем приложении. Передняя часть - Angular на https: // localhost: 4200, а внутренняя часть - Spring Boot на http: // localhost: 8080.

Эта проблема отличается от других, которые уже видели на SO, поскольку ни одна из описанных проблем не использует spring-boot-starter-oauth2-client из того, что я вижу.

Версия загрузки Spring - 2.4.1, и, как уже упоминалось, я использую spring-boot-starter-oauth2-client, который имеет следующую конфигурацию в реквизитах:

spring.security.oauth2.client.registration.facebook.client-id=ID_
spring.security.oauth2.client.registration.facebook.client-secret=SECRET_

Я настроил свой бэкэнд таким образом:

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors().and().csrf().disable()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .oauth2Login();
    }

и конфигурация CORS:

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*");
            }
        };
    }

Вначале все работает так, как ожидалось. Пока пользовательский интерфейс не прошел проверку подлинности, любой запрос к каким-либо конечным точкам приводит к ответу 302
Например:

Request URL: http://localhost:8080/me
Request Method: GET
Status Code: 302 
Remote Address: [::1]:8080
Referrer Policy: strict-origin-when-cross-origin

а в заголовках ответов есть:

Location: http://localhost:8080/oauth2/authorization/facebook

Итак, как и ожидалось, браузер выполняет еще один GET для ресурса из заголовка и получает другое перенаправление:

Request URL: http://localhost:8080/oauth2/authorization/facebook
Request Method: GET
Status Code: 302 
Remote Address: [::1]:8080
Referrer Policy: strict-origin-when-cross-origin

а URL-адрес перенаправления из заголовков ответов:

Location: https://www.facebook.com/v2.8/dialog/oauth?response_type=code&client_id=1239356666462449&scope=public_profile%20email&state=7zYPABCDE-88JBER2-POIKxRhzauv2Vhjcozo%3D&redirect_uri=http://localhost:8080/login/oauth2/code/facebook

но после того, как браузер выполняет еще один GET для данного URL-адреса, он получает ошибку CORS:

Access to XMLHttpRequest at 'https://www.facebook.com/v2.8/dialog/oauth?
response_type=code&client_id=1239356666462449&scope=public_profile%20email&
state=7zYPABCDE-88JBER2-POIKxRhzauv2Vhjcozo%3D&
redirect_uri=http://localhost:8080/login/oauth2/code/facebook' 
(redirected from 'http://localhost:8080/me') from origin 'https://localhost:4200' has been blocked by 
CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

В консоли это выглядит так:

Клиент Spring Boot oAuth2 с угловой проблемой CORS

Если я открою URL-адрес http://localhost:8080/me в адресной строке браузера, а не по запросу приложения, он, конечно, войдет в facebook, и все будет работать, как ожидалось.

Может ли кто-нибудь посоветовать мне, как мне продолжить, чтобы это работало? У меня кончились решения. Я знаю, что могу использовать прокси-сервер для отправки запросов, поэтому могу игнорировать проблему CORS. Но у меня интуитивное ощущение, что это необязательно и можно было бы сделать проще.

Большое спасибо всем, кто помог мне найти решение

Вы не можете запросить диалоговое окно входа в Facebook с помощью фонового запроса по той очень очевидной причине, что пользователи должны иметь возможность проверить через адресную строку, что они действительно отправляют свои учетные данные для входа в Facebook, а не на какой-то фишинговый сайт. Вам необходимо отправить пользователя на URL-адрес входа напрямую в его браузере.

CBroe 08.04.2021 09:18

Спасибо за ответ. Это означает, что я должен просто перехватить ответ и открыть всплывающее окно или что-то еще в моем интерфейсе, чтобы правильно работать, это правильно? Но что мне делать с ответом от Facebook? Но я до сих пор не понимаю, как это должно быть правильно реализовано и почему это работает так, как я бы хотел, когда я не использую приложение Angular для входа в систему, а просто перехожу к конечной точке /me в моем браузере.

Zychoo 08.04.2021 11:28

Кстати, люди, которые отрицательно отзываются - не могли бы вы написать комментарий, почему этот вопрос неуместен?

Zychoo 09.04.2021 12:27

Нет, скорее не во всплывающем окне - это процесс входа в систему с перенаправлением. Поэтому просто отправьте пользователю URL-адрес диалогового окна входа в то же окно, в котором он уже находится, после чего Facebook перенаправит обратно на указанный вами redirect_uri.

CBroe 09.04.2021 12:41
«Почему это работает так, как мне хотелось бы, когда я не использую приложение Angular для входа в систему, а просто перехожу к конечной точке / me в моем браузере». - потому что в этом случае перенаправление к диалога входа в систему, которое выполняет ваша конечная точка, происходит непосредственно во внешнем интерфейсе. Однако Angular пытается загрузить это через фоновый запрос, что означает, что перенаправление также «приземляется» в фоновом режиме, и поэтому он также пытается загрузить сам диалог входа в систему в фоновом режиме.
CBroe 09.04.2021 12:41

Это действительно открыло мне глаза, и я думаю, что, возможно, я смогу реализовать это так, как должен ;-) Большое спасибо @CBroe

Zychoo 09.04.2021 16:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
6
28
0

Другие вопросы по теме