mirror of
https://gitee.com/xiarenalofs/squad-rain-ops-mini.git
synced 2026-08-06 05:16:26 +08:00
204 lines
8.2 KiB
C#
204 lines
8.2 KiB
C#
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using System.Security.Claims;
|
|
using RainOpsMini.Helpers;
|
|
using RainOpsMini.Models;
|
|
using RainOpsMini;
|
|
|
|
namespace RainOpsMini.Apis
|
|
{
|
|
public static class AuthApi
|
|
{
|
|
public static void MapAuthApis(this IEndpointRouteBuilder app)
|
|
{
|
|
// API: 获取验证码
|
|
// 生成图形验证码用于登录验证
|
|
app.MapGet("/api/captcha", (IMemoryCache cache) =>
|
|
{
|
|
var (code, svg) = CaptchaHelper.GenerateCaptcha();
|
|
var id = Guid.NewGuid().ToString();
|
|
|
|
// 缓存验证码,有效期 5 分钟
|
|
cache.Set(id, code, TimeSpan.FromMinutes(5));
|
|
|
|
return Results.Ok(new { id, svg });
|
|
});
|
|
|
|
// API: 用户登录
|
|
// 验证用户名密码和验证码,发放 Cookie
|
|
app.MapPost("/api/login", async (LoginRequest req, HttpContext ctx, IMemoryCache cache) =>
|
|
{
|
|
// 校验验证码
|
|
if (string.IsNullOrEmpty(req.CaptchaId) || string.IsNullOrEmpty(req.CaptchaCode))
|
|
{
|
|
return Results.BadRequest(new { error = "请输入验证码" });
|
|
}
|
|
|
|
if (!cache.TryGetValue(req.CaptchaId, out string? correctCode) || correctCode == null)
|
|
{
|
|
return Results.BadRequest(new { error = "验证码已过期,请刷新" });
|
|
}
|
|
|
|
if (!string.Equals(correctCode, req.CaptchaCode, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return Results.BadRequest(new { error = "验证码错误" });
|
|
}
|
|
|
|
// 移除已使用的验证码
|
|
cache.Remove(req.CaptchaId);
|
|
|
|
// 1. 检查超级管理员账号 (配置文件中定义)
|
|
// 使用 Program.config 访问全局配置
|
|
if (req.Username == Program.Config.WebUser && req.Password == Program.Config.WebPassword)
|
|
{
|
|
var claims = new List<Claim>
|
|
{
|
|
new Claim(ClaimTypes.Name, req.Username),
|
|
new Claim("IsSuperAdmin", "true"),
|
|
new Claim("Permission", "all")
|
|
};
|
|
|
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
|
var authProperties = new AuthenticationProperties
|
|
{
|
|
IsPersistent = true
|
|
};
|
|
|
|
// 记录登录日志
|
|
try
|
|
{
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
db.Insertable(new RainOpsMini.Models.UserLoginLog
|
|
{
|
|
Username = req.Username,
|
|
LoginTime = DateTime.Now,
|
|
IpAddress = ctx.Connection.RemoteIpAddress?.ToString()
|
|
}).ExecuteCommand();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Failed to record login: {ex.Message}");
|
|
}
|
|
|
|
await ctx.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
|
|
return Results.Ok(new { redirect = "/", permissions = new List<string> { "all" } });
|
|
}
|
|
|
|
// 2. 检查子账号 (数据库中定义)
|
|
var user = UserStorage.GetByUsername(req.Username);
|
|
if (user != null && user.IsEnabled && user.Password == req.Password)
|
|
{
|
|
var claims = new List<Claim>
|
|
{
|
|
new Claim(ClaimTypes.Name, req.Username),
|
|
new Claim("IsSuperAdmin", "false")
|
|
};
|
|
|
|
// 合并用户权限和角色权限
|
|
var effectivePermissions = new HashSet<string>(user.Permissions);
|
|
if (!string.IsNullOrEmpty(user.RoleId))
|
|
{
|
|
var role = RoleStorage.GetById(user.RoleId);
|
|
if (role != null)
|
|
{
|
|
foreach (var p in role.Permissions)
|
|
{
|
|
effectivePermissions.Add(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (var perm in effectivePermissions)
|
|
{
|
|
claims.Add(new Claim("Permission", perm));
|
|
}
|
|
|
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
|
var authProperties = new AuthenticationProperties
|
|
{
|
|
IsPersistent = true
|
|
};
|
|
|
|
// 记录登录日志
|
|
try
|
|
{
|
|
using (var db = DbHelper.GetInstance())
|
|
{
|
|
db.Insertable(new RainOpsMini.Models.UserLoginLog
|
|
{
|
|
Username = req.Username,
|
|
LoginTime = DateTime.Now,
|
|
IpAddress = ctx.Connection.RemoteIpAddress?.ToString()
|
|
}).ExecuteCommand();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Failed to record login: {ex.Message}");
|
|
}
|
|
|
|
await ctx.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
|
|
return Results.Ok(new { redirect = "/", permissions = effectivePermissions.ToList() });
|
|
}
|
|
|
|
return Results.Unauthorized();
|
|
});
|
|
|
|
// API: 获取当前用户信息
|
|
// 返回当前登录用户的权限和角色信息
|
|
app.MapGet("/api/auth/me", (HttpContext ctx) =>
|
|
{
|
|
if (ctx.User.Identity?.IsAuthenticated != true) return Results.Unauthorized();
|
|
|
|
var isSuper = ctx.User.FindFirst("IsSuperAdmin")?.Value == "true";
|
|
var username = ctx.User.Identity.Name;
|
|
var perms = new List<string>();
|
|
|
|
// 重新获取最新权限 (避免 Cookie 中权限过期)
|
|
if (!isSuper && !string.IsNullOrEmpty(username))
|
|
{
|
|
var user = UserStorage.GetByUsername(username);
|
|
if (user != null)
|
|
{
|
|
var effectivePermissions = new HashSet<string>(user.Permissions);
|
|
if (!string.IsNullOrEmpty(user.RoleId))
|
|
{
|
|
var role = RoleStorage.GetById(user.RoleId);
|
|
if (role != null)
|
|
{
|
|
foreach (var p in role.Permissions)
|
|
{
|
|
effectivePermissions.Add(p);
|
|
}
|
|
}
|
|
}
|
|
perms = effectivePermissions.ToList();
|
|
}
|
|
}
|
|
else if (isSuper)
|
|
{
|
|
perms.Add("all");
|
|
}
|
|
|
|
return Results.Json(new
|
|
{
|
|
username,
|
|
isSuperAdmin = isSuper,
|
|
permissions = perms
|
|
});
|
|
});
|
|
|
|
// API: 退出登录
|
|
app.MapPost("/api/logout", async (HttpContext ctx) =>
|
|
{
|
|
await ctx.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
|
return Results.Ok();
|
|
});
|
|
}
|
|
}
|
|
} |