159 lines
4.4 KiB
C#
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
|