159 lines
4.4 KiB
C#

using AmtScanner.Api.Models;
using AmtScanner.Api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace AmtScanner.Api.Controllers;
/// <summary>
/// 认证控制器
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IAuthService _authService;
public AuthController(IAuthService authService)
{
_authService = authService;
}
/// <summary>
/// 用户登录
/// </summary>
[HttpPost("login")]
public async Task<ActionResult<ApiResponse<LoginResponse>>> Login([FromBody] LoginRequest request)
{
if (string.IsNullOrEmpty(request.UserName) || string.IsNullOrEmpty(request.Password))
{
return Ok(ApiResponse<LoginResponse>.Fail(400, "用户名和密码不能为空"));
}
var (user, accessToken, refreshToken, error) = await _authService.LoginAsync(request.UserName, request.Password);
if (error != null)
{
return Ok(ApiResponse<LoginResponse>.Fail(401, error));
}
var roles = await _authService.GetUserRolesAsync(user!.Id);
return Ok(ApiResponse<LoginResponse>.Success(new LoginResponse
{
Token = accessToken!,
RefreshToken = refreshToken!,
UserInfo = new UserInfoDto
{
UserId = user.Id,
UserName = user.UserName,
NickName = user.NickName ?? user.UserName,
Avatar = user.Avatar,
Email = user.Email,
Phone = user.Phone,
Gender = user.Gender,
Roles = roles
}
}, "登录成功"));
}
/// <summary>
/// 刷新 Token
/// </summary>
[HttpPost("refresh")]
public async Task<ActionResult<ApiResponse<RefreshTokenResponse>>> RefreshToken([FromBody] RefreshTokenRequest request)
{
if (string.IsNullOrEmpty(request.AccessToken) || string.IsNullOrEmpty(request.RefreshToken))
{
return Ok(ApiResponse<RefreshTokenResponse>.Fail(400, "Token 不能为空"));
}
var (accessToken, refreshToken, error) = await _authService.RefreshTokenAsync(request.AccessToken, request.RefreshToken);
if (error != null)
{
return Ok(ApiResponse<RefreshTokenResponse>.Fail(401, error));
}
return Ok(ApiResponse<RefreshTokenResponse>.Success(new RefreshTokenResponse
{
Token = accessToken!,
RefreshToken = refreshToken!
}, "刷新成功"));
}
/// <summary>
/// 退出登录
/// </summary>
[Authorize]
[HttpPost("logout")]
public async Task<ActionResult<ApiResponse<object>>> Logout()
{
var userIdClaim = User.FindFirst("userId")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !int.TryParse(userIdClaim, out var userId))
{
return Ok(ApiResponse<object>.Fail(401, "无效的用户"));
}
await _authService.LogoutAsync(userId);
return Ok(ApiResponse<object>.Success(null, "退出成功"));
}
}
#region DTOs
/// <summary>
/// 登录请求
/// </summary>
public class LoginRequest
{
public string UserName { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
/// <summary>
/// 登录响应
/// </summary>
public class LoginResponse
{
public string Token { get; set; } = string.Empty;
public string RefreshToken { get; set; } = string.Empty;
public UserInfoDto UserInfo { get; set; } = new();
}
/// <summary>
/// 用户信息 DTO
/// </summary>
public class UserInfoDto
{
public int UserId { get; set; }
public string UserName { get; set; } = string.Empty;
public string NickName { get; set; } = string.Empty;
public string? Avatar { get; set; }
public string? Email { get; set; }
public string? Phone { get; set; }
public string Gender { get; set; } = "0";
public List<string> Roles { get; set; } = new();
}
/// <summary>
/// 刷新 Token 请求
/// </summary>
public class RefreshTokenRequest
{
public string AccessToken { get; set; } = string.Empty;
public string RefreshToken { get; set; } = string.Empty;
}
/// <summary>
/// 刷新 Token 响应
/// </summary>
public class RefreshTokenResponse
{
public string Token { get; set; } = string.Empty;
public string RefreshToken { get; set; } = string.Empty;
}
#endregion