2026-05-21 15:52:36 +08:00
|
|
|
|
using Authentication;
|
2026-05-22 14:29:22 +08:00
|
|
|
|
using FileShare_Common.Core;
|
|
|
|
|
|
using FileShare_Services.Core;
|
|
|
|
|
|
using FileShare_Services.Services.AuthService;
|
2026-05-21 15:52:36 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
2026-05-22 14:29:22 +08:00
|
|
|
|
namespace FileShare_PC.Authentication
|
2026-05-21 15:52:36 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// PC 端鉴权端点服务,实现 <see cref="IPcAuthEndpointService"/>,
|
|
|
|
|
|
/// 处理授权码登录、Token 刷新和登出操作。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public sealed class PcAuthEndpointService(PcGlobalTokenService tokenService) : IPcAuthEndpointService
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <inheritdoc />
|
2026-05-22 11:18:47 +08:00
|
|
|
|
public async Task<IApiResponse> AuthorizeAsync(PcAuthorizeRequest request, ServiceEndpointContext ctx)
|
2026-05-21 15:52:36 +08:00
|
|
|
|
{
|
2026-05-22 11:18:47 +08:00
|
|
|
|
var token = await tokenService.AuthorizeAsync(request.AuthorizationCode);
|
2026-05-21 15:52:36 +08:00
|
|
|
|
if (token is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx.StatusCode = 401;
|
|
|
|
|
|
return ResponseHelper.Failure(401, "授权失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseHelper.Ok(token, "授权成功");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
2026-05-22 11:18:47 +08:00
|
|
|
|
public async Task<IApiResponse> RefreshAsync(PcRefreshRequest request, ServiceEndpointContext ctx)
|
2026-05-21 15:52:36 +08:00
|
|
|
|
{
|
2026-05-22 11:18:47 +08:00
|
|
|
|
var token = request.Token ?? ExtractBearerToken(ctx.GetHeader("Authorization"));
|
2026-05-21 15:52:36 +08:00
|
|
|
|
var refreshed = await tokenService.RefreshAsync(token);
|
|
|
|
|
|
if (refreshed is null)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx.StatusCode = 401;
|
|
|
|
|
|
return ResponseHelper.Failure(401, "授权已失效");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ResponseHelper.Ok(refreshed, "刷新成功");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
2026-05-22 11:18:47 +08:00
|
|
|
|
public Task<IApiResponse> LogoutAsync(PcLogoutRequest request, ServiceEndpointContext ctx)
|
2026-05-21 15:52:36 +08:00
|
|
|
|
{
|
2026-05-22 11:18:47 +08:00
|
|
|
|
var token = request.Token ?? ExtractBearerToken(ctx.GetHeader("Authorization"));
|
2026-05-21 15:52:36 +08:00
|
|
|
|
tokenService.Logout(token);
|
2026-05-22 11:18:47 +08:00
|
|
|
|
return Task.FromResult<IApiResponse>(ResponseHelper.Succeed("退出成功"));
|
2026-05-21 15:52:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <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();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|