Возвращение заголовка ответа OnAuthenticationFailed - PullRequest
1 голос
/ 29 апреля 2019

Я пытаюсь вернуть измененный заголовок, если срок действия маркера, отправленного пользователем, истек, чтобы я мог повторно отправить свой токен обновления, если срок его действия истек.

Я использую .NET Core 2.2 с хостингом In-Process, который имеет значение.

Вот мой ConfigureServices метод из моего Startup.cs.

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "bearer";
    options.DefaultChallengeScheme = "bearer";
}).AddJwtBearer("bearer", options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = false,
        ValidateIssuer = false,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration["serverSigningPassword"])),
        ValidateLifetime = true,
        ClockSkew = System.TimeSpan.Zero //the default for this setting is 5 minutes
    };
    options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }
            return System.Threading.Tasks.Task.CompletedTask;
        }
    };
});

И затем, когда я пытаюсь получить конечную точку «авторизации» из javascript со следующим.

async function fetchWithCredentials(url, options) {    
    options.headers['Authorization'] = 'Bearer ' + jwtToken;
    var response = await fetch(url, options);
    if (response.ok) { //all is good, return the response
        return response;
    }

    console.log(response.headers) //nothing in this array

    // it will never do this "if" statement because there are no headers
    if (response.status === 401 && response.headers.has('Token-Expired')) {
        // refresh the token
        return await fetchWithCredentials(url, options); //repeat the original request
    } else { //status is not 401 and/or there's no Token-Expired header
        return response; 
    }
}

Это изображение от наведения на заголовок. Это определенно достигает моей точки останова (для context.Response.Headers.Add(), и я вижу счетчик = 1 (который является «Истекшим токеном», когда я его проверяю).

enter image description here

Наконец, вот скриншот от Почтальона после неудачного запроса, поэтому ответ отправляется, но не принимается в моем JS. enter image description here

Есть идеи, почему мой заголовок не придерживается моего ответа в javascript?

Ответы [ 2 ]

2 голосов
/ 30 апреля 2019

Существует ограничение доступа к заголовкам ответов при использовании Fetch API через CORS.Из-за этого ограничения вы можете получить доступ только к следующим стандартным заголовкам:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

Ссылка: https://stackoverflow.com/a/44816592/5751404

Один из способов получить доступ к вашему заказузаголовок в клиенте должен добавить заголовок access-control-expose-headers к ответу, с разделенными запятыми заголовками:

services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
    builder.AllowAnyOrigin()
          .AllowAnyMethod()
          .AllowAnyHeader()
          .WithExposedHeaders("Token-Expired"); ;
}));

В Configure:

app.UseCors("MyPolicy");

, чтобы вы могли получить доступ кпользовательский заголовок от клиента, использующий Fetch API через CORS.

1 голос
/ 13 июня 2019

Здесь я опишу оба: 1. Срок действия токена истек и токен обновления 2. Только для неавторизованного запроса.

async function fetchWithCredentials(url, options) {    
    options.headers['Authorization'] = 'Bearer ' + jwtToken;
    var response = await fetch(url, options);//this is a function for get a response. I didn't explain it here. Hope you understand. 
    if (response.ok) {
        return response;
    }

    let flag:boolean=false; //set flag for executing one if statement at a time.

if (response.status == 401 && response.headers.has('Token-Expired')) {
        // refresh the token
        flag=true;  //set flag true.
        //write something as per your requirement.
    } 

if (response.status == 401 && flag==false) {
        **// Only for unauthorized request. You can use this for your problem.**
        //write something as per your requirement.
    } 
}

И самое главное, вы должны использовать приведенный ниже код в файле startup.cs.

services.AddCors(context => context.AddPolicy("CustomPolicy", builder =>
{
    builder.AllowAnyOrigin()
          .AllowAnyMethod()
          .AllowAnyHeader()
          .WithExposedHeaders("Token-Expired"); ;
}));

В Configure:

app.UseCors("CustomPolicy");

и используйте приведенный ниже код как есть.

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = "bearer";
    options.DefaultChallengeScheme = "bearer";
}).AddJwtBearer("bearer", options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateAudience = false,
        ValidateIssuer = false,
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(Configuration["serverSigningPassword"])),
        ValidateLifetime = true,
        ClockSkew = System.TimeSpan.Zero //the default for this setting is 5 minutes
    };
    options.Events = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
    {
        OnAuthenticationFailed = context =>
        {
            if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
            {
                context.Response.Headers.Add("Token-Expired", "true");
            }
            return System.Threading.Tasks.Task.CompletedTask;
        }
    };
});

Теперь вы получите ответ на стороне клиента.Надеюсь, вы найдете свое решение.Пожалуйста, дайте мне знать, если у вас возникли сомнения.

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