CSharp.Template/YuanXuan.IM.Api/Controllers/LoginAuthorController.cs

121 lines
4.3 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 Asp.Versioning;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using YuanXuan.IM.Common.Dtos.LoginMobile;
using YuanXuan.IM.Common.Helpers;
using YuanXuan.IM.Infrastructure.Redis;
namespace YuanXuan.IM.Api.Controllers
{
/// <summary>
/// 登录授权控制器
/// </summary>
[Route($@"{RoutePrefix}/[controller]/[action]")]
[ApiVersion(1.0)]
public class LoginAuthorController : BaseApiController
{
/// <summary>
/// 登录
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
// 这里应该添加实际的登录验证逻辑
// 暂时模拟登录成功
var userId = "123456";
var userName = "testuser";
// 生成JWT token
var token = JwtHelper.GenerateToken(userId, userName);
var refreshToken = JwtHelper.GenerateRefreshToken();
// 存储token到Redis用于后续的验证和登出
await RedisHelper.SetAsync($"user:token:{userId}", token, TimeSpan.FromHours(24));
await RedisHelper.SetAsync($"user:refreshToken:{userId}", refreshToken, TimeSpan.FromDays(7));
return Success(new { Token = token, RefreshToken = refreshToken, UserId = userId, UserName = userName });
}
/// <summary>
/// 刷新Token
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenRequest request)
{
// 验证refreshToken
var principal = JwtHelper.GetPrincipalFromExpiredToken(request.Token);
var userId = principal?.Claims.FirstOrDefault(c => c.Type == "sub")?.Value;
if (userId == null)
{
return Fail("无效的token");
}
var storedRefreshToken = await RedisHelper.GetStringAsync($"user:refreshToken:{userId}");
if (storedRefreshToken != request.RefreshToken)
{
return Fail("无效的refreshToken");
}
var userName = principal?.Claims.FirstOrDefault(c => c.Type == "name")?.Value;
var newToken = JwtHelper.GenerateToken(userId, userName);
var newRefreshToken = JwtHelper.GenerateRefreshToken();
await RedisHelper.SetAsync($"user:token:{userId}", newToken, TimeSpan.FromHours(24));
await RedisHelper.SetAsync($"user:refreshToken:{userId}", newRefreshToken, TimeSpan.FromDays(7));
return Success(new { Token = newToken, RefreshToken = newRefreshToken });
}
/// <summary>
/// 登出
/// </summary>
/// <returns></returns>
[Authorize]
[HttpPost]
public async Task<IActionResult> Logout()
{
var userId = User.FindFirst("sub")?.Value;
if (userId == null)
{
return Fail("用户未登录");
}
// 从Redis中删除token
await RedisHelper.DeleteAsync($"user:token:{userId}");
await RedisHelper.DeleteAsync($"user:refreshToken:{userId}");
return Success("登出成功");
}
/// <summary>
/// 全局登出(所有设备)
/// </summary>
/// <returns></returns>
[Authorize]
[HttpPost]
public async Task<IActionResult> GlobalLogout()
{
var userId = User.FindFirst("sub")?.Value;
if (userId == null)
{
return Fail("用户未登录");
}
// 删除所有相关的token
await RedisHelper.DeleteAsync($"user:token:{userId}");
await RedisHelper.DeleteAsync($"user:refreshToken:{userId}");
// 这里可以添加更多的清理逻辑,比如删除所有设备的登录记录
return Success("全局登出成功");
}
}
}