174 lines
5.2 KiB
C#
174 lines
5.2 KiB
C#
|
|
using Microsoft.Extensions.Configuration;
|
||
|
|
using Microsoft.Extensions.Logging;
|
||
|
|
using QYZH.InteractiveMagazine.IService;
|
||
|
|
using QYZH.InteractiveMagazine.IService.Dto;
|
||
|
|
using QYZH.InteractiveMagazine.Models.Common;
|
||
|
|
using QYZH.InteractiveMagazine.Models.Settings;
|
||
|
|
using QYZH.InteractiveMagazine.Infrastructure.Auth;
|
||
|
|
|
||
|
|
namespace QYZH.InteractiveMagazine.Service;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 认证服务实现
|
||
|
|
/// </summary>
|
||
|
|
public class AuthService : IAuthService
|
||
|
|
{
|
||
|
|
private readonly IConfiguration _configuration;
|
||
|
|
private readonly ILogger<AuthService> _logger;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 演示用管理员账号
|
||
|
|
/// </summary>
|
||
|
|
private const string DemoAccount = "admin";
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 演示用管理员密码
|
||
|
|
/// </summary>
|
||
|
|
private const string DemoPassword = "123456";
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 构造函数
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="configuration">配置</param>
|
||
|
|
/// <param name="logger">日志记录器</param>
|
||
|
|
public AuthService(IConfiguration configuration, ILogger<AuthService> logger)
|
||
|
|
{
|
||
|
|
_configuration = configuration;
|
||
|
|
_logger = logger;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 用户登录
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="account">账号</param>
|
||
|
|
/// <param name="password">密码</param>
|
||
|
|
/// <returns>登录结果</returns>
|
||
|
|
public async Task<LoginOutput> LoginAsync(string account, string password)
|
||
|
|
{
|
||
|
|
_logger.LogInformation("用户登录尝试,账号: {Account}", account);
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(account))
|
||
|
|
{
|
||
|
|
throw new BusinessException("账号不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(password))
|
||
|
|
{
|
||
|
|
throw new BusinessException("密码不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 演示版本:硬编码验证账号密码
|
||
|
|
if (account != DemoAccount || password != DemoPassword)
|
||
|
|
{
|
||
|
|
_logger.LogWarning("用户登录失败,账号: {Account}", account);
|
||
|
|
throw new BusinessException("账号或密码错误", 401);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 获取JWT配置
|
||
|
|
var jwtSettings = GetJwtSettings();
|
||
|
|
|
||
|
|
// 生成令牌
|
||
|
|
var token = JwtHelper.GenerateToken(1, "管理员", jwtSettings);
|
||
|
|
var refreshToken = JwtHelper.GenerateToken(1, "管理员", jwtSettings);
|
||
|
|
|
||
|
|
_logger.LogInformation("用户登录成功,账号: {Account}", account);
|
||
|
|
|
||
|
|
return new LoginOutput
|
||
|
|
{
|
||
|
|
Token = token,
|
||
|
|
RefreshToken = refreshToken,
|
||
|
|
UserId = 1,
|
||
|
|
UserName = "管理员"
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 用户注册
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="input">注册输入参数</param>
|
||
|
|
/// <returns>是否成功</returns>
|
||
|
|
public async Task<bool> RegisterAsync(RegisterInput input)
|
||
|
|
{
|
||
|
|
_logger.LogInformation("用户注册尝试,账号: {Account}", input?.Account);
|
||
|
|
|
||
|
|
if (input == null)
|
||
|
|
{
|
||
|
|
throw new BusinessException("注册参数不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(input.Account))
|
||
|
|
{
|
||
|
|
throw new BusinessException("账号不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(input.Password))
|
||
|
|
{
|
||
|
|
throw new BusinessException("密码不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(input.UserName))
|
||
|
|
{
|
||
|
|
throw new BusinessException("用户名不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 演示版本:模拟注册成功
|
||
|
|
_logger.LogInformation("用户注册成功,账号: {Account}, 用户名: {UserName}", input.Account, input.UserName);
|
||
|
|
|
||
|
|
return await Task.FromResult(true);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 刷新令牌
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="refreshToken">刷新令牌</param>
|
||
|
|
/// <returns>新的登录结果</returns>
|
||
|
|
public async Task<LoginOutput> RefreshTokenAsync(string refreshToken)
|
||
|
|
{
|
||
|
|
_logger.LogInformation("令牌刷新尝试");
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(refreshToken))
|
||
|
|
{
|
||
|
|
throw new BusinessException("刷新令牌不能为空", 400);
|
||
|
|
}
|
||
|
|
|
||
|
|
var jwtSettings = GetJwtSettings();
|
||
|
|
|
||
|
|
// 生成新的令牌
|
||
|
|
var newToken = JwtHelper.GenerateToken(1, "管理员", jwtSettings);
|
||
|
|
var newRefreshToken = JwtHelper.GenerateToken(1, "管理员", jwtSettings);
|
||
|
|
|
||
|
|
_logger.LogInformation("令牌刷新成功");
|
||
|
|
|
||
|
|
return new LoginOutput
|
||
|
|
{
|
||
|
|
Token = newToken,
|
||
|
|
RefreshToken = newRefreshToken,
|
||
|
|
UserId = 1,
|
||
|
|
UserName = "管理员"
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 获取JWT配置
|
||
|
|
/// </summary>
|
||
|
|
/// <returns>JWT配置对象</returns>
|
||
|
|
private JwtSettings GetJwtSettings()
|
||
|
|
{
|
||
|
|
var jwtSettings = _configuration.GetSection("JwtSettings").Get<JwtSettings>()
|
||
|
|
?? new JwtSettings
|
||
|
|
{
|
||
|
|
Issuer = "QYZH.InteractiveMagazine",
|
||
|
|
Audience = "QYZH.InteractiveMagazine.Client",
|
||
|
|
SecretKey = "QYZH_InteractiveMagazine_SecretKey_2024",
|
||
|
|
ExpiryMinutes = 120
|
||
|
|
};
|
||
|
|
|
||
|
|
if (string.IsNullOrWhiteSpace(jwtSettings.SecretKey))
|
||
|
|
{
|
||
|
|
throw new BusinessException("JWT配置不完整", 500);
|
||
|
|
}
|
||
|
|
|
||
|
|
return jwtSettings;
|
||
|
|
}
|
||
|
|
}
|