.NET CORE API с Angular 4 - токен cookie и токен запроса поменялись местами

Я продолжаю получать это сообщение при попытке реализовать XSRF с Angular и .NET CORE: «Проверка предоставленного токена защиты от подделки не удалась. Токен cookie и токен запроса поменялись местами». У меня имена файлов cookie и заголовков настроены одинаково как в Angular, так и в API. У кого-нибудь есть идеи?

Процесс

Angular выполняет первоначальный вызов этого метода API для получения файла cookie.

    [HttpGet("startSession")]
    public async Task<IActionResult> StartSession()
    {
        AntiforgeryTokenSet tokens = this.antiForgery.GetAndStoreTokens(this.HttpContext);

        this.HttpContext.Response.Cookies.Append(this.options.Value.Cookie.Name, tokens.RequestToken, new CookieOptions { HttpOnly = false });

        return this.Ok(
            new
            {
                Success = true
            });
    }

Затем Angular перехватывает следующий запрос POST и немного переопределяет обработку XSRF по умолчанию, поскольку мне нужно, чтобы он работал с URL-адресами HTTPS.

    // Override default Angular XSRF handling since it won't work for         
    absolute URLs and we have to prefix with "https://"
    // Source:https://github.com/angular/angular/blob/master/packages/common/http/src/xsrf.ts
    @Injectable()
    export class HchbHttpXsrfInterceptor implements HttpInterceptor {
    constructor(
    private tokenService: HttpXsrfTokenExtractor) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): 
    Observable<HttpEvent<any>> {
    const headerName = 'X-XSRF-TOKEN';
    const lcUrl = req.url.toLowerCase();
    // Skip both non-mutating requests.
    // Non-mutating requests don't require a token
    // anyway as the cookie set
    // on our origin is not the same as the token expected by another origin.
    if (req.method === 'GET' || req.method === 'HEAD' ) {
         return next.handle(req);
    }
    const token = this.tokenService.getToken();

    // Be careful not to overwrite an existing header of the same name.
    if (token !== null && !req.headers.has(headerName)) {
       req = req.clone({headers: req.headers.set(headerName, token)});
    }
    return next.handle(req);
    }
    }

person Bob B.    schedule 21.03.2018    source источник


Ответы (1)


Я столкнулся с той же проблемой, и я думаю, что нашел проблему. options.Cookie.Name в AddAntiforgery должен отличаться от файла cookie, который вы установили вручную с помощью context.Response.Cookies.Append.

Попробуйте изменить имя одного из них, и это сработает. Прямо сейчас вы заменяете сгенерированный файл cookie, в котором используется имя options.Cookie.Name, на значение tokens.RequestToken.

Вы можете заметить разницу в инструментах разработчика.

  • Токен по умолчанию, созданный с использованием options.Cookie.Name, помечен как http only (HttpOnly = true)
  • Прикрепленный вручную токен с использованием context.Response.Cookies.Append помечен как HttpOnly = false

Второй читается из JS / Angular (вы можете прочитать его в JS, потому что HttpOnly=false и отправляется в качестве заголовка в ваших запросах ajax и проверяется на соответствие по умолчанию, которое не может быть прочитано из JS)

person Corneliu    schedule 21.04.2018
comment
Извините, забыл обновить это, но ваш ответ правильный. Я теперь не устанавливаю имя cookie при запуске, и все начало работать! - person Bob B.; 23.04.2018