Reputation: 33
Here is LoginDisplay.razor, in /Shared:
<AuthorizeView>
<Authorized>
<a href="Identity/Account/Manage">Hello, @context.User.Identity?.Name!</a>
<form method="POST" action="/Identity/Account/Logout">
<button type="submit" class="nav-link btn btn-link">Log out</button>
</form>
</Authorized>
<NotAuthorized>
<a href="Identity/Account/Register">Register</a>
<a href="Identity/Account/Login">Log in</a>
</NotAuthorized>
</AuthorizeView>
Here is Logout.cshtml, located in /Areas/Identity/Pages/Account:
@page
@model LogoutModel
@{
ViewData["Title"] = "Log out";
}
<header>
<h1>@ViewData["Title"]</h1>
@{
if (User.Identity?.IsAuthenticated ?? false)
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
</form>
}
else
{
<p>You have successfully logged out of the application.</p>
}
}
</header>
And finally here is Logout.cshtml.cs, also located in /Areas/Identity/Pages/Account:
#nullable disable
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using RecipeAZ.Areas.Identity.Data;
namespace RecipeAZ.Areas.Identity.Pages.Account
{
public class LogoutModel : PageModel
{
private readonly SignInManager<AppUser> _signInManager;
private readonly ILogger<LogoutModel> _logger;
public LogoutModel(SignInManager<AppUser> signInManager, ILogger<LogoutModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
public async Task<IActionResult> OnPost(string returnUrl = null)
{
Console.WriteLine("log out");
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
if (returnUrl != null)
{
return LocalRedirect(returnUrl);
}
else
{
// This needs to be a redirect so that the browser performs a new
// request and the identity for the user gets updated.
return RedirectToPage();
}
}
}
}
When I click the logout button in LoginDisplay, it goes to a blank page, and the Console.Writeline in OnPost doesn't execute, nor does a breakpoint in OnPost trigger. However, if I enter the url directly(http://localhost:5000/Identity/Account/Logout), it displays Logout.cshtml, and I can successfully log out from the button it has.
If I change the form in LoginDisplay to a get method, and OnPost to OnGet, the logout button logs me out and redirects to the login page. However, from here when I click on the log in button I'm logged in then immediately logged back out and returned once again to the log in page. The address shown at this point is "http://localhost:5000/Identity/Account/Login?ReturnUrl=%2FIdentity%2FAccount%2FLogout" which i suspect is why it immediately logs me out again. So changing it to a get method doesn't fix it after all, and my understanding is that using get methods in this way is bad practice.
I'm obviously a beginner here, so any help at all would be appreciated.
Upvotes: 1
Views: 601
Reputation: 5164
The issue is actually about antiforgery token. You can add [IgnoreAntiforgeryToken]
on top of LogoutModel
:
[IgnoreAntiforgeryToken]
public class LogoutModel : PageModel
{
//...
}
You can check more information in this GitHub Issue.
Upvotes: 0