Files
emall-api/FutureMailAPI/Services/AuthService.cs
2025-10-16 09:56:36 +08:00

168 lines
6.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FutureMailAPI.Helpers;
using FutureMailAPI.DTOs;
using System.Security.Claims;
namespace FutureMailAPI.Services
{
public interface IAuthService
{
Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto);
Task<ApiResponse<AuthResponseDto>> RegisterAsync(UserRegisterDto registerDto);
Task<ApiResponse<bool>> ValidateTokenAsync(string token);
Task<ApiResponse<string>> RefreshTokenAsync(string token);
Task<ApiResponse<AuthResponseDto>> LoginWithOAuthAsync(UserLoginDto loginDto, string clientId, string clientSecret);
}
public class AuthService : IAuthService
{
private readonly IUserService _userService;
private readonly IPasswordHelper _passwordHelper;
private readonly IOAuthService _oauthService;
public AuthService(
IUserService userService,
IPasswordHelper passwordHelper,
IOAuthService oauthService)
{
_userService = userService;
_passwordHelper = passwordHelper;
_oauthService = oauthService;
}
public async Task<ApiResponse<AuthResponseDto>> LoginAsync(UserLoginDto loginDto)
{
// 使用默认客户端ID和密钥进行OAuth登录
// 在实际应用中,这些应该从配置中获取
var defaultClientId = "futuremail_default_client";
var defaultClientSecret = "futuremail_default_secret";
return await LoginWithOAuthAsync(loginDto, defaultClientId, defaultClientSecret);
}
public async Task<ApiResponse<AuthResponseDto>> LoginWithOAuthAsync(UserLoginDto loginDto, string clientId, string clientSecret)
{
// 创建OAuth登录请求
var oauthLoginDto = new OAuthLoginDto
{
UsernameOrEmail = loginDto.UsernameOrEmail,
Password = loginDto.Password,
ClientId = clientId,
ClientSecret = clientSecret,
Scope = "read write" // 默认权限范围
};
// 使用OAuth服务进行登录
var oauthResult = await _oauthService.LoginAsync(oauthLoginDto);
if (!oauthResult.Success)
{
return ApiResponse<AuthResponseDto>.ErrorResult(oauthResult.Message ?? "登录失败");
}
// 获取用户信息
var userResult = await _userService.GetUserByUsernameOrEmailAsync(loginDto.UsernameOrEmail);
if (!userResult.Success || userResult.Data == null)
{
return ApiResponse<AuthResponseDto>.ErrorResult("获取用户信息失败");
}
var user = userResult.Data;
// 创建用户响应DTO
var userResponse = new UserResponseDto
{
Id = user.Id,
Username = user.Username,
Email = user.Email,
Nickname = user.Nickname,
Avatar = user.Avatar,
CreatedAt = user.CreatedAt,
LastLoginAt = DateTime.UtcNow
};
// 创建认证响应DTO使用OAuth令牌
var authResponse = new AuthResponseDto
{
Token = oauthResult.Data.AccessToken,
RefreshToken = oauthResult.Data.RefreshToken,
Expires = DateTime.UtcNow.AddSeconds(oauthResult.Data.ExpiresIn),
User = userResponse
};
return ApiResponse<AuthResponseDto>.SuccessResult(authResponse, "登录成功");
}
public async Task<ApiResponse<AuthResponseDto>> RegisterAsync(UserRegisterDto registerDto)
{
// 检查用户名是否已存在
var existingUserResult = await _userService.GetUserByUsernameAsync(registerDto.Username);
if (existingUserResult.Success && existingUserResult.Data != null)
{
return ApiResponse<AuthResponseDto>.ErrorResult("用户名已存在");
}
// 检查邮箱是否已存在
var existingEmailResult = await _userService.GetUserByEmailAsync(registerDto.Email);
if (existingEmailResult.Success && existingEmailResult.Data != null)
{
return ApiResponse<AuthResponseDto>.ErrorResult("邮箱已被注册");
}
// 创建用户
var createUserResult = await _userService.CreateUserAsync(registerDto);
if (!createUserResult.Success)
{
return ApiResponse<AuthResponseDto>.ErrorResult(createUserResult.Message ?? "注册失败");
}
// 注册成功后自动使用OAuth登录
var loginDto = new UserLoginDto
{
UsernameOrEmail = registerDto.Username,
Password = registerDto.Password
};
return await LoginAsync(loginDto);
}
public async Task<ApiResponse<bool>> ValidateTokenAsync(string token)
{
// 注意在OAuth 2.0中令牌验证应该由OAuth中间件处理
// 这里我们暂时返回成功实际使用时应该通过OAuth 2.0的令牌验证流程
return ApiResponse<bool>.SuccessResult(true);
}
public async Task<ApiResponse<string>> RefreshTokenAsync(string token)
{
// 在OAuth 2.0中刷新令牌需要客户端ID和密钥
// 这里我们使用默认客户端凭据
var defaultClientId = "futuremail_default_client";
var defaultClientSecret = "futuremail_default_secret";
// 创建OAuth刷新令牌请求
var oauthTokenRequest = new OAuthTokenRequestDto
{
ClientId = defaultClientId,
ClientSecret = defaultClientSecret,
RefreshToken = token,
GrantType = "refresh_token",
Scope = "read write"
};
// 使用OAuth服务刷新令牌
var oauthResult = await _oauthService.RefreshTokenAsync(oauthTokenRequest);
if (!oauthResult.Success)
{
return ApiResponse<string>.ErrorResult(oauthResult.Message ?? "刷新令牌失败");
}
// 返回新的访问令牌
return ApiResponse<string>.SuccessResult(oauthResult.Data.AccessToken, "令牌刷新成功");
}
}
}