token基础demo
【需求】
Home/Index 登录界面,校验成功后可以登录到Main/Index ,用户登录3分钟内关闭网站,再次访问Home/Index时可以免密登录Main/Index
【配置文件-Program.cs】
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
//加一个session
builder.Services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(3); // 3分钟过期
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
//使用session
app.UseSession();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
【实现-后端HomeController】
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Login(string username, string password)
{
if (username == "1" && password == "100")//省略数据库读取步骤,假设校验成功了
{
CreateToken(HttpContext);//设置token
return RedirectToAction("Index", "Main");//重定向到已登录界面
}
ViewBag.ErrorMessage = "登录失败,账密错误";
return View("Index");//否则重定向到本页
}
private const string TokenSessionKey = "AuthToken";
private const string TokenExpiryKey = "TokenExpiry";
public static void CreateToken(HttpContext context)//创建token
{
var token = Guid.NewGuid().ToString();//设置token
var expiry = DateTime.Now.AddMinutes(3);//设置过期日期
context.Session.SetString(TokenSessionKey, token);
context.Session.SetString(TokenExpiryKey, expiry.ToString("o")); // 使用 ISO 8601 格式
}
}
}
【实现-后端MainController】
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1.Controllers
{
public class MainController : Controller
{
public IActionResult Index()
{
if (!ValidateToken(HttpContext))//判断是否携带有效token
{
return RedirectToAction("Index", "Home");//不是则重定向到登录界面
}
return View();//否则重定向到本页(已登录页面)
}
private const string TokenSessionKey = "AuthToken";
private const string TokenExpiryKey = "TokenExpiry";
public static bool ValidateToken(HttpContext context)
{
var token = context.Session.GetString(TokenSessionKey);//尝试获取token
var expiryString = context.Session.GetString(TokenExpiryKey);//尝试获取过期日期
if (token == null || expiryString == null)
{
return false;//获取不到表明不是登陆状态
}
var expiry = DateTime.Parse(expiryString, null, System.Globalization.DateTimeStyles.RoundtripKind);//使用 ISO 8601 格式解析日期
return DateTime.Now <= expiry;//判断是否过期,如果过期返回false
}
}
}
【前端-Home/Index】登录界面
@{
ViewData["Title"] = "Home";
}
<h1>Login</h1>
<form method="post" action="/Home/Login">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username" required />
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required />
</div>
<button type="submit">Login</button>
</form>
@if (ViewBag.ErrorMessage != null)
{
<p style="color:red;">@ViewBag.ErrorMessage</p>
}
【小结】
1.HttpContext是当前 HTTP 请求的上下文信息,它提供了有关请求和响应的各种数据和服务。
2.以上demo写法不查数据库,不封装AuthService
服务类,仅为展示基本的逻辑
3.前后端交互需要对应控制器名称、控制器下的方法名称
4.使用 ISO 8601 格式(例如 "o")来存储日期时间值,是为了确保日期时间的标准化和一致性
5.token 进行免登录时,需要后端管理或存储 token,方法有二:(本demo未展示此点)
- 一是服务器或redis存储token
- 二是使用JWT将用户信息+过期时间嵌入 token 中,后端可以验证 token 的有效性,而不需要存储 token 本身。
拓展
Q:如果需要增加注销功能,应该如何实现?
A :Main/Index加一个注销按钮,MainController清除token和过期时间即可
后端:
// 触发注销方法
public IActionResult Logout()
{
HttpContext.Session.Remove(TokenSessionKey); // 清除 token
HttpContext.Session.Remove(TokenExpiryKey); // 清除过期时间
return RedirectToAction("Index", "Home"); // 注销后重定向到主页
}
前端:
<button onclick="logout()">Logout</button> <!-- 注销按钮 -->
<script>
function logout() {
fetch('/Main/Logout', { // 调用后端的 Logout 方法
method: 'POST', // 使用 POST 请求
headers: {
'Content-Type': 'application/json'
},
credentials: 'same-origin' // 确保发送会话 cookie
})
.then(response => {
if (response.ok) {
window.location.href = '/Home/Index'; // 注销成功后重定向到主页
} else {
console.error('Logout failed');
}
})
.catch(error => console.error('Error:', error));
}
</script>
标签:Web,return,Index,C#,app,token,Session,Home,public
From: https://blog.csdn.net/m0_67412019/article/details/141144216