Files
ASP.NET-CORE-web-test/Endpoints/UserEndpoints.cs
2025-10-10 16:02:38 +08:00

120 lines
4.6 KiB
C#

using FluentValidation;
using Microsoft.EntityFrameworkCore;
using SimpleTodoApiWithPg.Data;
using SimpleTodoApiWithPg.Models;
using SimpleTodoApiWithPg.UserService;
using System.ComponentModel.DataAnnotations;
namespace SimpleTodoApiWithPg.Endpoints
{
public static class UserEndpoints
{
public static void MapUserEndpoints ( this WebApplication app)
{
var usersApi = app.MapGroup("/users")
.CacheOutput()
.RequireAuthorization()
.WithTags("Users");
usersApi.MapGet("/", async (UserServices userService) =>
{
return await userService.GetUsersAsync();
}).WithTags("获取所有用户");
usersApi.MapGet("/{id}", async (Guid id, UserServices userService) =>
{
return await userService.GetoneUserAsync(id);
}).WithTags("根据id获取对应的用户信息");
usersApi.MapPost("/", async (RegisterRequest request, UserServices userService) =>
{
var response = await userService.RegisterAsync(request);
if (!response.Success)
{
return Results.BadRequest(response);
}
return Results.Ok(response);
}).WithTags("用户注册接口")
.AllowAnonymous()
.AddEndpointFilter<ValidationFilter<RegisterRequest>>()
.ProducesValidationProblem();
usersApi.MapPatch("/{id}", async (int id, UpdateUserRequest updateUser, UserServices userService) =>
{
return await userService.UpdateUserAsync(id, updateUser);
}).WithTags("用户信息更新接口");
usersApi.MapDelete("/{id}", async (Guid id,UserServices userService) =>
{
return await userService.DeleteUserAsync(id);
}).WithTags("删除用户接口");
var loginauthApi = app.MapGroup("/api/auth")
.CacheOutput()
.WithTags("登录认证接口!");
loginauthApi.MapPost("/", async (UserServices userService, LoginRequest loginRequest) =>
{
var response = await userService.LoginAuthAsync(loginRequest);
// 如果登录失败,返回一个带有错误码和错误信息的 BadRequest
if (!response.Success)
{
return Results.BadRequest(response);
}
return Results.Ok(response);
}).WithTags("登录认证授权接口!");
// --- 新增刷新令牌端点 ---
loginauthApi.MapPost("/refresh-token", async (
/* 这里可以定义一个DTO来接收RefreshToken */
RefreshTokenRequest refreshToken,
AppDbContext dbContext,
UserServices userServices /* 注入UserServices来复用逻辑 */
) =>
{
// 通过传入的 refreshToken 查找数据库中对应的记录
var storedToken = await dbContext.RefreshTokens
.Include(rt => rt.User) // 同时加载关联的用户信息
.FirstOrDefaultAsync(rt => rt.Token == refreshToken.RefreshToken);
// 检查令牌是否存在、是否有效
if (storedToken == null || !storedToken.IsActive)
{
return Results.BadRequest("无效的刷新令牌。");
}
// (安全增强) 使旧的刷新令牌失效
storedToken.Revoked = DateTime.UtcNow;
// 生成新的访问令牌
var newAccessTokenExpiration = DateTime.UtcNow.AddMinutes(1);
var newAccessToken = userServices.GenerateJwtToken(storedToken.User, newAccessTokenExpiration); // 需要将 GenerateJwtToken 访问修饰符改为 public 或 internal
// 生成新的刷新令牌
var newRefreshToken = userServices.GenerateRefreshToken(); // GenerateRefreshToken 也需要 public/internal
newRefreshToken.UserId = storedToken.UserId;
await dbContext.RefreshTokens.AddAsync(newRefreshToken);
await dbContext.SaveChangesAsync();
return Results.Ok(new AuthResponse
{
AccessToken = newAccessToken,
RefreshToken = newRefreshToken.Token,
AccessTokenExpiration = newAccessTokenExpiration
});
})
.WithTags("刷新令牌接口");
}
}
}