Повторный вызов моего API возвращает Preflight Ошибка состояния HTTP - PullRequest
0 голосов
/ 15 апреля 2020

Я боролся со странной проблемой уже около недели. Я искал ответы здесь и в других местах на inte rnet, и я не совсем уверен, в чем может заключаться моя конкретная проблема c. Однако я думаю, что полученное сообщение об ошибке не имеет ничего общего с моей действительной ошибкой. Я благодарю вас за любую помощь или предложения, которые могут у вас возникнуть.

Мои настройки следующие (все работают локально):

  1. Веб-сайт Frontend - Angular - работает на стандартном ng serve
  2. Backend API - PHP / MySQL - размещено локально через XAMPP

Ошибка:

{"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":"http://192.168.64.2/resourcer/api/menu/47693eb3-ca82-467b-af68-020150a5e4a6","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://192.168.64.2/resourcer/api/menu/47693eb3-ca82-467b-af68-020150a5e4a6: 0 Unknown Error","error":{"isTrusted":true}}

Концепция:

  1. Войдите, авторизуйтесь на стороне php, получите токен jwt.
  2. У токена jwt есть свойство, называемое «доступ». Я использую это для возврата меню, основанного на роли.
  3. Как только я получаю jwt, я устанавливаю пользовательский объект, добавляю jwt к заголовку авторизации токена носителя.
  4. Вызовите вызов меню извлечения со свойством доступа, полученным с сервера.

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

Я успешно вхожу в систему, получаю jwt и объект пользователя, но когда я запрашиваю меню, я получаю сообщение об ошибке. Я не могу пройти это вообще. Единственный способ исправить это - комментировать весь код, необходимый для возврата в меню, и просто выводить «ok». Затем я делаю запрос, получаю ОК, раскомментирую код, а затем все возвращается в нормальное состояние, пока я снова не выйду из системы.

Понятия не имею, что происходит на земле. Вот мой код:

Angular Служба перехватчика:

export class InterceptorService implements HttpInterceptor {
  constructor(private authService: AuthService) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler,
  ): Observable<HttpEvent<any>> {
    const currentUser = this.authService.currentUserValue;

    if (currentUser && currentUser.token) {
      request = request.clone({
        setHeaders: {
          'Content-Type': 'application/json; charset=utf-8',
          Accept: 'application/json',
          Authorization: `Bearer ${currentUser.token}`,
        },
      });
    } else {
      request = request.clone({
        setHeaders: {
          'Content-Type': 'application/json; charset=utf-8',
          Accept: 'application/json',
        },
      });
    }

    return next.handle(request);
  }
}

Angular Служба аутентификации:

signIn(signinCredentials: AuthCredentials) {
    return this.dataService.signIn(signinCredentials).pipe(
      map((data) => {
        const helper = new JwtHelperService();
        const decoded = helper.decodeToken(data.jwt);
        const user: User = decoded.data;
        user.token = data.jwt;

        localStorage.setItem('currentUser', JSON.stringify(user));
        this.currentUserSubject.next(user);
        return user;
      }),
    );
  }

logout() {
    localStorage.removeItem('currentUser');
    localStorage.removeItem('navItems');
    this.currentUserSubject.next(null);
  }

Angular Страница входа в систему:

signIn() {
    this.submitted = true;
    this.loading = true;

    this.authService
      .signIn(this.signinCredentials)
      .pipe(first())
      .subscribe(
        (data) => {
          this.currentUser = this.authService.currentUserValue;
          this.getMenu();
        },
        (error) => {
          this.error = error;
          this.loading = false;
        },
      );
  }

getMenu() {
    this.dataService.getNavigationItems(this.currentUser.access).subscribe(
      (menu) => {
        if (menu) {
          this.envService.setNavItems(menu.menu);
          this.router.navigate([this.returnUrl]);
        } else {
          this.authService.logout();
          location.reload(true);
        }
      },
      (error) => {
        this.authService.logout();
        location.reload(true);
      },
    );
  }

Теперь на моей стороне PHP я использую файл .htaccess для перенаправления своего URL:

RewriteEngine on
RewriteRule app/api/ app/api/index.php

PHP Индекс:

<?php

header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Origin, Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

define('PROJECT_ROOT_PATH', __DIR__);

include_once 'config/db.php';

--- Controller imports etc happen here

$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$uri = explode('/', $uri);
$requestMethod = $_SERVER["REQUEST_METHOD"];

$headerToken = getBearerToken();

if (isset($uri[3])) {
    switch ($uri[3]) {
        case 'users':
            $userId = null;
            if (isset($uri[4])) {
                $userId = (int) $uri[4];
            }
            $controller = new UserController($db, $requestMethod, $userId, $headerToken);
            $controller->processRequest();
            break;
        case 'companies':
            $companyReference = null;
            if (isset($uri[4])) {
                $companyReference = $uri[4];
            }
            $controller = new CompanyController($db, $requestMethod, $companyReference, $headerToken);
            $controller->processRequest();
            break;
        case 'login':
            $controller = new LoginController($db);
            $controller->login();
            break;
        case 'menu':
            $roleGuid = null;
            if (isset($uri[4])) {
                $roleGuid = $uri[4];
            }
            $controller = new MenuController($db, $roleGuid, $headerToken);
            $controller->getMenuItems();
            break;
        default:
            header("HTTP/1.1 404 Not Found");
            exit();
    }
} else {
    header("HTTP/1.1 404 Not Found");
    exit();
}

function getAuthorizationHeader()
{
    $headers = null;
    if (isset($_SERVER['Authorization'])) {
        $headers = trim($_SERVER["Authorization"]);
    } else if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
        $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
    } elseif (function_exists('apache_request_headers')) {
        $requestHeaders = apache_request_headers();
        $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
        if (isset($requestHeaders['Authorization'])) {
            $headers = trim($requestHeaders['Authorization']);
        }
    }
    return $headers;
}

function getBearerToken()
{
    $headers = getAuthorizationHeader();
    if (!empty($headers)) {
        if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
            return $matches[1];
        }
    }
    return null;
}

Когда я упомянул, что я закомментировал код контроллера с помощью echo ok, и это работает, происходит в этом индексном файле.

Я в тупике.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...