- 为全部 5 个项目(Avalonia-API、Avalonia-Common、Avalonia-EFCore、 Avalonia-PC、Avalonia-Services)中缺失注释的类、方法、属性、字段、 接口成员等补全中文 XML 文档注释 - 共修改约 37 个文件,补全约 220+ 处注释 - 修复 ServiceEndpointCollection.cs 中 MapDelete<TService> 语法错误 - 修复 PcAuthService.cs 中 const prefix 位置错乱导致编译失败的问题 - 扫描结果:缺失项 0 - 构建结果:4/4 项目编译通过
95 lines
3.5 KiB
C#
95 lines
3.5 KiB
C#
using Authentication;
|
||
using Avalonia_Common.Core;
|
||
using Avalonia_Services.Core;
|
||
using Avalonia_Services.Services.AuthService;
|
||
using System;
|
||
using System.Text.Json;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Avalonia_PC.Authentication
|
||
{
|
||
/// <summary>
|
||
/// PC 端鉴权端点服务,实现 <see cref="IPcAuthEndpointService"/>,
|
||
/// 处理授权码登录、Token 刷新和登出操作。
|
||
/// </summary>
|
||
public sealed class PcAuthEndpointService(PcGlobalTokenService tokenService) : IPcAuthEndpointService
|
||
{
|
||
private static readonly JsonSerializerOptions JsonOptions = new()
|
||
{
|
||
PropertyNameCaseInsensitive = true,
|
||
};
|
||
|
||
/// <inheritdoc />
|
||
public async Task<object?> AuthorizeAsync(ServiceEndpointContext ctx)
|
||
{
|
||
var request = Deserialize<PcAuthorizeRequest>(ctx.Body);
|
||
var token = await tokenService.AuthorizeAsync(request?.AuthorizationCode);
|
||
if (token is null)
|
||
{
|
||
ctx.StatusCode = 401;
|
||
return ResponseHelper.Failure(401, "授权失败");
|
||
}
|
||
|
||
return ResponseHelper.Ok(token, "授权成功");
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public async Task<object?> RefreshAsync(ServiceEndpointContext ctx)
|
||
{
|
||
var request = Deserialize<PcRefreshRequest>(ctx.Body);
|
||
var token = request?.Token ?? ExtractBearerToken(ctx.GetHeader("Authorization"));
|
||
var refreshed = await tokenService.RefreshAsync(token);
|
||
if (refreshed is null)
|
||
{
|
||
ctx.StatusCode = 401;
|
||
return ResponseHelper.Failure(401, "授权已失效");
|
||
}
|
||
|
||
return ResponseHelper.Ok(refreshed, "刷新成功");
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public Task<object?> LogoutAsync(ServiceEndpointContext ctx)
|
||
{
|
||
var request = Deserialize<PcLogoutRequest>(ctx.Body);
|
||
var token = request?.Token ?? ExtractBearerToken(ctx.GetHeader("Authorization"));
|
||
tokenService.Logout(token);
|
||
return Task.FromResult<object?>(ResponseHelper.Succeed("退出成功"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将 JSON 请求体反序列化为指定类型。
|
||
/// </summary>
|
||
/// <typeparam name="T">目标类型。</typeparam>
|
||
/// <param name="body">JSON 请求体字符串,可为空。</param>
|
||
/// <returns>反序列化后的对象;若 body 为空则返回默认值。</returns>
|
||
private static T? Deserialize<T>(string? body)
|
||
{
|
||
return string.IsNullOrWhiteSpace(body)
|
||
? default
|
||
: JsonSerializer.Deserialize<T>(body, JsonOptions);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从 Authorization 头中提取 Bearer Token。
|
||
/// </summary>
|
||
/// <param name="authorization">Authorization 头的值。</param>
|
||
/// <returns>提取的 Token 字符串;若无法提取则返回 null。</returns>
|
||
private static string? ExtractBearerToken(string? authorization)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(authorization))
|
||
{
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Bearer Token 的前缀常量。
|
||
/// </summary>
|
||
const string prefix = "Bearer ";
|
||
return authorization.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)
|
||
? authorization[prefix.Length..].Trim()
|
||
: authorization.Trim();
|
||
}
|
||
}
|
||
}
|