feat(auth): 添加统一 API 和 PC 认证端点

- 新增 API 端 JWT 登录、refresh token 轮换和退出登录流程
- 新增 refresh token 实体、DbSet 配置和 EF Core 迁移
- 新增 PC 端授权码登录、本地全局 token 刷新、登出和鉴权服务
- 扩展统一端点模型,支持宿主过滤、角色鉴权、OpenAPI 元数据和 DI 服务处理器
- API 启用 JwtBearer 认证、Swagger UI 和认证端点注册
- PC 端注册认证服务,并按宿主过滤桌面拦截端点
This commit is contained in:
2026-05-15 17:35:07 +08:00
parent c5f741e6a4
commit a9abd90874
26 changed files with 1295 additions and 31 deletions
@@ -0,0 +1,49 @@
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Avalonia_EFCore.Models
{
/// <summary>
/// API refresh token。只保存哈希,不保存明文 token。
/// </summary>
[Comment("API refresh token")]
[Table("api-refresh-token")]
public class ApiRefreshTokenEntity
{
[Key]
[Column("id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Column("user-id")]
public int UserId { get; set; }
[Column("token-hash")]
[MaxLength(128)]
public string TokenHash { get; set; } = string.Empty;
[Column("created-at")]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
[Column("expires-at")]
public DateTime ExpiresAt { get; set; }
[Column("revoked-at")]
public DateTime? RevokedAt { get; set; }
[Column("replaced-by-token-hash")]
[MaxLength(128)]
public string? ReplacedByTokenHash { get; set; }
[Column("device")]
[MaxLength(200)]
public string? Device { get; set; }
[Column("ip-address")]
[MaxLength(64)]
public string? IpAddress { get; set; }
public bool IsActive => RevokedAt is null && ExpiresAt > DateTime.UtcNow;
}
}