This commit is contained in:
2026-07-24 12:42:51 +08:00 Unverified
commit 67905dfa16
56 changed files with 7630 additions and 0 deletions
@@ -0,0 +1,90 @@
using System.ComponentModel.DataAnnotations;
using System.Security.Claims;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace Jiaowu.Api.Controllers;
[ApiController]
[Route("api/auth")]
public sealed class AuthController(
UserManager<ApplicationUser> userManager,
ITokenService tokenService) : ControllerBase
{
[AllowAnonymous]
[HttpPost("login")]
public async Task<ActionResult<LoginResponse>> Login(LoginRequest request)
{
var user = await userManager.FindByNameAsync(request.UserName);
if (user is null || !user.IsEnabled)
{
return Unauthorized(new ProblemDetails
{
Title = "登录失败",
Detail = "账号或密码不正确,或账号已停用。",
Status = StatusCodes.Status401Unauthorized
});
}
if (await userManager.IsLockedOutAsync(user) ||
!await userManager.CheckPasswordAsync(user, request.Password))
{
await userManager.AccessFailedAsync(user);
return Unauthorized(new ProblemDetails
{
Title = "登录失败",
Detail = "账号或密码不正确,或账号已停用。",
Status = StatusCodes.Status401Unauthorized
});
}
await userManager.ResetAccessFailedCountAsync(user);
user.LastLoginAt = DateTime.UtcNow;
await userManager.UpdateAsync(user);
var roles = await userManager.GetRolesAsync(user);
return new LoginResponse(
tokenService.Create(user, roles),
new CurrentUserResponse(
user.Id,
user.UserName!,
user.DisplayName,
roles,
user.CollegeId));
}
[Authorize]
[HttpGet("me")]
public async Task<ActionResult<CurrentUserResponse>> Me()
{
var id = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = id is null ? null : await userManager.FindByIdAsync(id);
if (user is null || !user.IsEnabled)
{
return Unauthorized();
}
return new CurrentUserResponse(
user.Id,
user.UserName!,
user.DisplayName,
await userManager.GetRolesAsync(user),
user.CollegeId);
}
}
public sealed record LoginRequest(
[Required, MaxLength(100)] string UserName,
[Required, MaxLength(100)] string Password);
public sealed record LoginResponse(string Token, CurrentUserResponse User);
public sealed record CurrentUserResponse(
Guid Id,
string UserName,
string DisplayName,
IEnumerable<string> Roles,
Guid? CollegeId);