Last active
November 7, 2024 23:27
-
-
Save zola-25/5a814b7f1bf28840ee939ba45776c723 to your computer and use it in GitHub Desktop.
Maintaining User Session State with Cookies - Raw, Library-free Implementation with ASP.NET Core MVC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Security.Cryptography; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.AspNetCore.Mvc; | |
namespace CookieSessionStateDemo.Controllers | |
{ | |
public static class InMemoryDataStore | |
{ | |
public static readonly Dictionary<string, string> UserSessions = new(); | |
public static readonly Dictionary<string, string> UserCredentials = new() { { "user1", "password1" }, { "user2", "password2" } }; | |
} | |
public class Credentials | |
{ | |
public string Username { get; set; } | |
public string Password { get; set; } | |
} | |
public class HomeController : Controller | |
{ | |
[HttpGet] | |
public IActionResult Index() | |
{ | |
string? sessionId = HttpContext.Request.Cookies["sessionId"]; | |
bool isLoggedIn = sessionId != null && InMemoryDataStore.UserSessions.ContainsKey(sessionId); | |
if (isLoggedIn) | |
{ | |
var username = InMemoryDataStore.UserSessions[sessionId!]; | |
return View(model: username); | |
} | |
else | |
{ | |
return RedirectToAction("Login"); | |
} | |
} | |
[HttpGet("Login")] | |
public IActionResult Login() | |
{ | |
return View(); | |
} | |
[ValidateAntiForgeryToken] | |
[HttpPost("Login")] | |
public IActionResult LoginSubmit([FromForm] Credentials credentials) | |
{ | |
string username = credentials.Username; | |
string password = credentials.Password; | |
if (InMemoryDataStore.UserCredentials.ContainsKey(username) && InMemoryDataStore.UserCredentials[username] == password) | |
{ | |
string sessionId = GenerateSessionId(); | |
InMemoryDataStore.UserSessions.Add(sessionId, username); | |
HttpContext.Response.Cookies.Append("sessionId", sessionId, new CookieOptions() | |
{ | |
Secure = true, | |
HttpOnly = true, | |
SameSite = SameSiteMode.Strict, | |
Path = "/" | |
}); | |
return RedirectToAction("Index"); | |
} | |
else | |
{ | |
return Unauthorized("Invalid username or password. Please try again."); | |
} | |
} | |
[ValidateAntiForgeryToken] | |
[HttpPost("Logout")] | |
public IActionResult Logout() | |
{ | |
string? sessionId = HttpContext.Request.Cookies["sessionId"]; | |
if (sessionId != null && InMemoryDataStore.UserSessions.ContainsKey(sessionId)) | |
{ | |
InMemoryDataStore.UserSessions.Remove(sessionId); | |
HttpContext.Response.Cookies.Delete("sessionId"); | |
} | |
return RedirectToAction("Login"); | |
} | |
string GenerateSessionId() | |
{ | |
byte[] randomBytes = RandomNumberGenerator.GetBytes(32); | |
return Convert.ToBase64String(randomBytes); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@model string | |
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Restricted Page</title> | |
</head> | |
<body> | |
<h1>Restricted Home Page</h1> | |
Welcome @Model, you are authorized. | |
<h2>Logout?</h2> | |
<form method="post" asp-action="Logout" asp-controller="Home"> | |
<button type="submit">Logout</button> | |
</form> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Session Auth Cookie Login</title> | |
</head> | |
<body> | |
<h1>Login</h1> | |
<form method="post" asp-action="LoginSubmit" asp-controller="Home"> | |
<label> | |
Username: | |
<input type="text" name="username" required> | |
</label> | |
<br> | |
<label> | |
Password: | |
<input type="password" name="password" required> | |
</label> | |
<br> | |
<button type="submit">Login</button> | |
</form> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var builder = WebApplication.CreateBuilder(args); | |
builder.Services.AddControllersWithViews(); | |
var app = builder.Build(); | |
app.UseHttpsRedirection(); | |
app.UseRouting(); | |
app.MapControllerRoute( | |
name: "default", | |
pattern: "{controller=Home}/{action=Index}"); | |
app.Run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment