121 lines
4.3 KiB
C#
121 lines
4.3 KiB
C#
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("全局登出成功");
|
||
}
|
||
}
|
||
}
|