簡體   English   中英

重新加載頁面影響注銷用戶/注銷

[英]Reloading page affecting sign out of user/log out

我已經嘗試過多次修復此問題,但到目前為止都沒有成功。 我正在登錄我的頁面,一切正常。 然而,每次我重新加載我的頁面時,我最終都會注銷並重定向到“登錄頁面”並且必須重新登錄。 問題是什么? 我的 Coockie 邏輯有問題嗎?

我也嘗試過實現login.RememberMe邏輯,但它也不起作用。 我檢查過login.RememberMe返回 true,但沒有效果。

controller登錄方法:

[HttpPost]
public async Task<IActionResult> Login([FromBody] LoginModel login)
{
  ApplicationUser user = await this.SignInManager.UserManager.FindByEmailAsync(login.Email);

  Microsoft.AspNetCore.Identity.SignInResult result =
    await this.SignInManager.PasswordSignInAsync(login.Email, login.Password, login.RememberMe, false);

  if (!result.Succeeded)
  {
    List<string> errors = new List<string>();
    errors.Add("Email and password are invalid.");
    return BadRequest(new LoginResult
    {
      Successful = false,
      Errors = errors,
    });
  }

  IList<string> roles = await this.SignInManager.UserManager.GetRolesAsync(user);

  List<Claim> claims = new List<Claim>
  {
    new Claim(ClaimTypes.Name, login.Email)
  };

  ClaimsIdentity identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
  ClaimsPrincipal principal = new ClaimsPrincipal(identity);
  AuthenticationProperties props = new AuthenticationProperties
  {
    IsPersistent = true,
    ExpiresUtc = DateTime.UtcNow.AddMonths(1)
  };

  // to register the cookie to the browser
  this.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, props).Wait();

  foreach (string role in roles)
  {
    claims.Add(new Claim(ClaimTypes.Role, role));
  }

  SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.Configuration["JwtSecurityKey"]));
  SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  DateTime expiry = DateTime.Now.AddDays(Convert.ToInt32(this.Configuration["JwtExpiryInDays"]));

  JwtSecurityToken token = new JwtSecurityToken(
    this.Configuration["JwtIssuer"],
    this.Configuration["JwtAudience"],
    claims,
    expires: expiry,
    signingCredentials: creds
  );

  return Ok(new LoginResult
  {
    Successful = true,
    Token = new JwtSecurityTokenHandler().WriteToken(token),
  });
}

啟動.cs:

public void ConfigureServices(IServiceCollection services)
{
  services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
      options.TokenValidationParameters = new TokenValidationParameters
      {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = Configuration["JwtIssuer"],
        ValidAudience = Configuration["JwtAudience"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSecurityKey"]))
      };
    })
    .AddCookie(options =>
     {
       options.Cookie.Name = "DashCoockie";
       options.LoginPath = "/login";
       options.ExpireTimeSpan = TimeSpan.FromDays(30);
       options.SlidingExpiration = true; 
       options.EventsType = typeof(CookieAuthEvent);
     });
  services.AddScoped<CookieAuthEvent>();

  services.AddAuthorization(config =>
  {
    config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());
    config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());
  });

  services.ConfigureApplicationCookie(options =>
  {
    options.Cookie.HttpOnly = true;
    options.Events.OnRedirectToLogin = context =>
    {
      context.Response.StatusCode = 401;
      return Task.CompletedTask;
    };
  });

  services.AddControllers();

  // Instant update on runtime for development purposes
  services.AddControllersWithViews().AddRazorRuntimeCompilation();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
  app.UseAuthentication();
  app.UseAuthorization();

  app.UseCookiePolicy();
}

CookieAuthEvent.cs:

  public class CookieAuthEvent : CookieAuthenticationEvents
  {
      public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
      {
          context.Request.HttpContext.Items.Add("ExpiresUTC", context.Properties.ExpiresUtc);
      }
  }

登錄后(Coockie 名稱相同,只是隱藏了上面代碼中的第一部分):

在此處輸入圖像描述

我的項目結構如下:Client、Server、Shared。 我通過在客戶端使用 LocalStorage 和 AuthService: IAuthService 找到了解決方案。 那么在我的設置中唯一的解決方案是使用 LocalStorage 嗎?

public class AuthService : IAuthService
{
    private readonly HttpClient _httpClient;
    private readonly AuthenticationStateProvider _authenticationStateProvider;
    private readonly ILocalStorageService _localStorage;

    public AuthService(HttpClient httpClient,
                       AuthenticationStateProvider authenticationStateProvider,
                       ILocalStorageService localStorage)
    {
        _httpClient = httpClient;
        _authenticationStateProvider = authenticationStateProvider;
        _localStorage = localStorage;
    }

    public async Task<RegisterResult> Register(RegisterModel registerModel)
    {
        var result = await _httpClient.PostJsonAsync<RegisterResult>("api/accounts", registerModel);

        return result;
    }

    public async Task<LoginResult> Login(LoginModel loginModel)
    {
        var loginAsJson = JsonSerializer.Serialize(loginModel);
        var response = await _httpClient.PostAsync("api/Login", new StringContent(loginAsJson, Encoding.UTF8, "application/json"));
        var loginResult = JsonSerializer.Deserialize<LoginResult>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

        if (!response.IsSuccessStatusCode)
        {
            return loginResult;
        }

        await _localStorage.SetItemAsync("authToken", loginResult.Token);
        ((ApiAuthenticationStateProvider)_authenticationStateProvider).MarkUserAsAuthenticated(loginModel.Email);
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", loginResult.Token);

        return loginResult;
    }

    public async Task Logout()
    {
        await _localStorage.RemoveItemAsync("authToken");
        ((ApiAuthenticationStateProvider)_authenticationStateProvider).MarkUserAsLoggedOut();
        _httpClient.DefaultRequestHeaders.Authorization = null;
    }
}

看來你沒有在你的請求 header 中設置令牌嘗試在你的啟動 class 中添加這些代碼:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.Events = new JwtBearerEvents()
                        {
                            OnMessageReceived = context =>
                              {
                                  context.Token = context.Request.Cookies["access_token"];
                                  return Task.CompletedTask;
                              }
                        };
                    });

在您的登錄操作中:

Response.Cookies.Append("access_token",your JwtSecurityToken)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM