Files
sharp-basic/test/NetServer.Test/Examples/Controllers/AuthController.cs
T
2025-12-30 09:17:25 +08:00

219 lines
6.4 KiB
C#

using Sharp.NetServer.Attributes;
using Sharp.NetServer.Controllers;
using Sharp.NetServer.Models;
using Sharp.NetServer.Abstractions;
using System.Security.Claims;
namespace NetServer.Test.Examples.Controllers;
/// <summary>
/// 认证控制器示例
/// </summary>
[ApiController]
[Route("api/auth")]
public class AuthController : BaseController
{
// 模拟用户数据库
private static readonly Dictionary<string, string> UserCredentials = new()
{
{ "admin", "admin123" },
{ "user", "user123" }
};
/// <summary>
/// 用户登录
/// POST /api/auth/login
/// Body: { "username": "admin", "password": "admin123" }
/// </summary>
[AllowAnonymous]
[RateLimit(10, RateLimitScope.Ip)] // 防止暴力破解
[HttpPost("login")]
public async Task LoginAsync(HttpContext context)
{
var loginData = await ReadJsonBodyAsync<Dictionary<string, string>>(context);
if (loginData == null ||
!loginData.TryGetValue("username", out var username) ||
!loginData.TryGetValue("password", out var password))
{
await BadRequestAsync(context, "用户名和密码不能为空");
return;
}
// 验证凭据
if (UserCredentials.TryGetValue(username, out var correctPassword) &&
correctPassword == password)
{
// 生成简单的 Token(实际应用中应使用 JWT)
var token = GenerateSimpleToken(username);
// 设置 Cookie
SetCookie(context, "auth_token", token, 3600);
await WriteSuccessResponseAsync(context, new
{
token,
username,
role = username == "admin" ? "Admin" : "User",
expiresIn = 3600
}, "登录成功");
}
else
{
await UnauthorizedAsync(context, "用户名或密码错误");
}
}
/// <summary>
/// 用户登出
/// POST /api/auth/logout
/// </summary>
[Authorize]
[HttpPost("logout")]
public async Task LogoutAsync(HttpContext context)
{
// 删除 Cookie
DeleteCookie(context, "auth_token");
await WriteSuccessResponseAsync(context, new { }, "登出成功");
}
/// <summary>
/// 获取当前用户信息
/// GET /api/auth/me
/// </summary>
[Authorize]
[HttpGet("me")]
public async Task GetCurrentUserAsync(HttpContext context)
{
var username = context.User?.Identity?.Name ?? "Unknown";
var roles = context.User?.Claims
.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value)
.ToList() ?? new List<string>();
await WriteSuccessResponseAsync(context, new
{
username,
roles,
isAuthenticated = context.User?.Identity?.IsAuthenticated ?? false
});
}
/// <summary>
/// 修改密码
/// POST /api/auth/change-password
/// Body: { "oldPassword": "admin123", "newPassword": "newpass123" }
/// </summary>
[Authorize]
[RateLimit(5, RateLimitScope.User)]
[HttpPost("change-password")]
public async Task ChangePasswordAsync(HttpContext context)
{
var username = context.User?.Identity?.Name;
if (string.IsNullOrEmpty(username))
{
await UnauthorizedAsync(context);
return;
}
var passwordData = await ReadJsonBodyAsync<Dictionary<string, string>>(context);
if (passwordData == null ||
!passwordData.TryGetValue("oldPassword", out var oldPassword) ||
!passwordData.TryGetValue("newPassword", out var newPassword))
{
await BadRequestAsync(context, "旧密码和新密码不能为空");
return;
}
// 验证旧密码
if (!UserCredentials.TryGetValue(username, out var currentPassword) ||
currentPassword != oldPassword)
{
await BadRequestAsync(context, "旧密码错误");
return;
}
// 更新密码
UserCredentials[username] = newPassword;
await WriteSuccessResponseAsync(context, new { }, "密码修改成功");
}
/// <summary>
/// 刷新 Token
/// POST /api/auth/refresh
/// </summary>
[Authorize]
[HttpPost("refresh")]
public async Task RefreshTokenAsync(HttpContext context)
{
var username = context.User?.Identity?.Name;
if (string.IsNullOrEmpty(username))
{
await UnauthorizedAsync(context);
return;
}
var newToken = GenerateSimpleToken(username);
SetCookie(context, "auth_token", newToken, 3600);
await WriteSuccessResponseAsync(context, new
{
token = newToken,
expiresIn = 3600
}, "Token 刷新成功");
}
private static string GenerateSimpleToken(string username)
{
// 简单的 Token 生成(实际应用中应使用 JWT)
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var role = username == "admin" ? "Admin" : "User";
return Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes($"{username}:{role}:{timestamp}")
);
}
}
/// <summary>
/// 简单的认证提供者实现
/// </summary>
public class SimpleAuthenticationProvider : IAuthenticationProvider
{
public Task<ClaimsPrincipal?> AuthenticateAsync(string? token)
{
if (string.IsNullOrEmpty(token))
return Task.FromResult<ClaimsPrincipal?>(null);
try
{
// 解析简单的 Token
var decoded = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(token));
var parts = decoded.Split(':');
if (parts.Length >= 2)
{
var username = parts[0];
var role = parts[1];
var claims = new List<Claim>
{
new(ClaimTypes.Name, username),
new(ClaimTypes.Role, role)
};
var identity = new ClaimsIdentity(claims, "SimpleAuth");
var principal = new ClaimsPrincipal(identity);
return Task.FromResult<ClaimsPrincipal?>(principal);
}
}
catch
{
// Token 解析失败
}
return Task.FromResult<ClaimsPrincipal?>(null);
}
}