168 lines
6.6 KiB
C#
168 lines
6.6 KiB
C#
|
|
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, "令牌刷新成功");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|