Cors запрос с symfony / угловой

0

Я все еще должен найти решение и искать проблему CORS. Чтобы решить эту проблему, я настроил свою конфигурацию следующим образом:

Проект на сервере: Debian 8/nginx/php-fpm

Мой Nginx vhost:

server {
    server_name sub.domain.com;
    root /home/projects/sub.domain.com/web;

    location / {
        try_files $uri /app.php$is_args$args;
    }


    # DEV
    location ~ ^/(app_dev|config)\.php(/|$) {
                fastcgi_pass unix:/var/run/php5-fpm-user.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }

    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm-user.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        internal;
    }

}

Серверная часть: Symfony 3.0 с FosUserBundle/FOSRestBundle/NelmioApiDocBundle/NelmioCorsBundle/LexikJWTAuthenticationBundle/JMSSerializer

Мой config.yml:

# FosUserBundle Configuration
fos_user:
    db_driver: orm
    firewall_name: main
    user_class: UserBundle\Entity\User
    group:
        group_class: UserBundle\Entity\Group
        form:
            type: UserBundle\Form\Type\GroupFormType
    profile:
        form:
            type: UserBundle\Form\Type\ProfileFormType

# FOSRestBundle Configuration
fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener: true
    view:
        view_response_listener: 'force'
        formats:
            xml: true
            json : true
        templating_formats:
            html: true
        force_redirects:
            html: true
        failed_validation: HTTP_BAD_REQUEST
        default_engine: twig
    routing_loader:
        default_format: json

# LexikJWTAuthenticationBundle Configuration
lexik_jwt_authentication:
    private_key_path: %jwt_private_key_path%
    public_key_path:  %jwt_public_key_path%
    pass_phrase:      %jwt_key_pass_phrase%
    token_ttl:        %jwt_token_ttl%

# JMSSerializer Configuration
jms_serializer:
    metadata:
        auto_detection: true

# NelmioCorsBundle Configuration
nelmio_cors:
    defaults:
        allow_credentials: true
        allow_origin: []
        allow_headers: []
        allow_methods: []
        expose_headers: []
        max_age: 0
        hosts: []
        origin_regex: false
    paths:
        '^/api/':
            allow_origin: ['*']
            allow_headers: ['Origin', 'Content-Type', 'X-Requested-With', 'Accept']
            allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
            max_age: 3600

Мой security.yml:

api_doc:
    pattern: ^/api/doc
    anonymous: true

api_login:
    pattern:  ^/api/login
    provider: fos_userbundle
    stateless: true
    anonymous: true
    form_login:
        check_path:     /api/login_check
        require_previous_session: false
        username_parameter: username
        password_parameter: password
        success_handler:          lexik_jwt_authentication.handler.authentication_success
        failure_handler:          lexik_jwt_authentication.handler.authentication_failure

api:
    pattern:   ^/api
    stateless: true
    provider: fos_userbundle
    lexik_jwt:
        authorization_header:
            enabled: true
            prefix:  Bearer
        query_parameter:
            enabled: true
            name:    Bearer
        throw_exceptions:        true
        create_entry_point:      true

## Main firewall
main:
    pattern: ^/
    form_login:
        provider: fos_userbundle
        csrf_token_generator: security.csrf.token_manager
        login_path: fos_user_security_login
        check_path: fos_user_security_check
        remember_me: true
        default_target_path: lgb_onepage_home
    logout:
        path:   fos_user_security_logout
        target: lgb_onepage_home
    anonymous: true
    remember_me:
        secret:      %secret%
        lifetime: 604800 # 1 week in seconds
        path:     /
        domain:   ~ # Defaults to the current domain from $_SERVER
        #                secure:   true
        httponly: true

access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/register, role: ROLE_ADMIN }
    - { path: ^/resetting, role: ROLE_ADMIN }
    - { path: ^/intranet/, role: ROLE_USER }
    - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/api,       roles: [IS_AUTHENTICATED_FULLY, ROLE_ADMIN] }

И для моего клиента я использую Ionic с угловым JS на базовом проекте (с вкладками скелета для правильной формы входа):

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

.config(function ($stateProvider, $urlRouterProvider, localStorageServiceProvider, $httpProvider) {
    $stateProvider...;

    // if none of the above states are matched, use this as the fallback
    $urlRouterProvider.otherwise('/app/playlists');

    localStorageServiceProvider
        .setPrefix('lgb-preorder');

    $httpProvider.defaults.headers.common = {};
    $httpProvider.defaults.headers.post = {};
    $httpProvider.defaults.headers.put = {};
    $httpProvider.defaults.headers.patch = {};
});

и моя функция (не работает):

$scope.doLogin = function () {

            var loginData = {
                username: this.login.username,
                password: this.login.password
            };

            $http({
                url: 'http://sub.domain.com/app_dev.php/api/login_check',
                method: 'POST',
                data: loginData,
                headers: {'Content-Type': 'application/json'}
            })
                .success(function (data) {
                    console.log("Success -- login ok with ", data);
                })
                .error(function (error) {
                    console.log("ERROR -- login fail with ", error);
                });
        };

Ошибка отправки:

XMLHttpRequest cannot load http://sub.domain.com/app_dev.php/api/login_check. Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values '*, http://localhost:8100', but only one is allowed. Origin 'http://localhost:8100' is therefore not allowed access.

кажется, потому что мой запрос HTTP имеет 2 определения Access-Control-Allow-Headers и Access-Control-Allow-Origin:

Request URL:http://sub.domain.com/app_dev.php/api/login_check
Request Method:OPTIONS
Status Code:200 OK
Remote Address:x.x.x.x:80
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Headers:origin, content-type, x-requested-with, accept
Access-Control-Allow-Methods:POST, PUT, GET, DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost:8100
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600

но почему???____???

Если у кого-то есть идея, ее действительно оценят =) Thanx за вашу помощь


Этот запрос CURL работает:

curl -X POST http://sub.domain.com/app_dev.php/api/login_check -d '{"username": "user", "password": "pass"}' -H "Content-Type: application/json"
  • 0
    какой веб-сервер вы используете? Вы уверены, что веб-сервер не добавляет дополнительный Access-Control-Allow-Origin? ..
  • 0
    Я использовал Nginx, я добавляю свой виртуальный хост в этой конфигурации. Я не знаю, может ли nginx добавить заголовок в этом запросе.
Теги:
fosuserbundle
fosrestbundle

1 ответ

1

У меня была такая же проблема с OPTIONS. Мой backend - весна. Я нашел что-то эквивалентное для PHP.

Работа с Корсом

Вам нужно сосредоточиться на предполетном освещении. Я думаю, вам нужно добавить это в свой внутренний код.

  // respond to preflights
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  // return only the headers and not the content
  // only allow CORS if we're doing a GET - i.e. no saving for now.
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'GET') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: X-Requested-With');
  }
  exit;
}
  • 0
    Спасибо за ваш ответ. Я не понимаю, как эта конфигурация может удалить один из этих заголовков? : si прочитал пост remysharp, но эта тема очень специфична.
  • 0
    У меня мало знаний php. gist.github.com/alexjs/4165271 gist.github.com/Stanback/7145487 . Я нашел что-то для nginx. Может быть, вы можете сделать в конфигурации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню