Files
tiku-backend.net/Tiku.Api/Controllers/AuthController.cs
2026-07-26 13:18:18 +08:00

140 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

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 Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Tiku.Application.Auth;
using Tiku.Api.Contracts;
namespace Tiku.Api.Controllers;
[ApiController]
[Route("api/auth")]
[Produces("application/json")]
public sealed class AuthController(IAuthService authService) : ControllerBase
{
[AllowAnonymous]
[HttpPost("login/password")]
[EndpointSummary("手机号密码登录")]
[EndpointDescription("使用本地手机号和密码登录,签发 JWT access token 与数据库 refresh/session。")]
[ProducesResponseType<AuthenticatedUserDto>(StatusCodes.Status200OK)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<AuthenticatedUserDto>> LoginWithPassword(
[FromBody] PasswordLoginDto request,
CancellationToken cancellationToken)
{
var result = await authService.LoginWithPasswordAsync(
new PasswordLoginRequest(
request.TenantId,
request.Phone,
request.Password,
GetIpAddress(),
Request.Headers.UserAgent.ToString()),
cancellationToken);
return Ok(AuthenticatedUserDto.FromApplication(result));
}
[AllowAnonymous]
[HttpPost("login/sms")]
[EndpointSummary("短信验证码登录")]
[EndpointDescription("校验已发送的登录用途短信验证码,成功后签发 JWT access token 与数据库 refresh/session。")]
[ProducesResponseType<AuthenticatedUserDto>(StatusCodes.Status200OK)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status401Unauthorized)]
public async Task<ActionResult<AuthenticatedUserDto>> LoginWithSms(
[FromBody] SmsLoginDto request,
CancellationToken cancellationToken)
{
var result = await authService.LoginWithSmsAsync(
new SmsLoginRequest(
request.TenantId,
request.Phone,
request.Code,
GetIpAddress(),
Request.Headers.UserAgent.ToString()),
cancellationToken);
return Ok(AuthenticatedUserDto.FromApplication(result));
}
[AllowAnonymous]
[HttpPost("oauth/wechat")]
[EndpointSummary("微信网页 OAuth 登录")]
[EndpointDescription("使用微信网页授权 code 换取 openid/unionidupsert 用户身份并创建应用会话。")]
[ProducesResponseType<AuthenticatedUserDto>(StatusCodes.Status200OK)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status401Unauthorized)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status503ServiceUnavailable)]
public async Task<ActionResult<AuthenticatedUserDto>> LoginWithWechatWeb(
[FromBody] OAuthCodeDto request,
CancellationToken cancellationToken)
{
var result = await authService.LoginWithWechatWebAsync(
new WechatLoginRequest(
request.TenantId,
request.Code,
GetIpAddress(),
Request.Headers.UserAgent.ToString()),
cancellationToken);
return Ok(AuthenticatedUserDto.FromApplication(result));
}
[AllowAnonymous]
[HttpPost("oauth/wechat-miniapp")]
[EndpointSummary("微信小程序登录")]
[EndpointDescription("使用小程序 wx.login 返回的 code 换取 openid/session_keyupsert 用户身份并创建应用会话。")]
[ProducesResponseType<AuthenticatedUserDto>(StatusCodes.Status200OK)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status401Unauthorized)]
[ProducesResponseType<ProblemDetails>(StatusCodes.Status503ServiceUnavailable)]
public async Task<ActionResult<AuthenticatedUserDto>> LoginWithWechatMiniApp(
[FromBody] OAuthCodeDto request,
CancellationToken cancellationToken)
{
var result = await authService.LoginWithWechatMiniAppAsync(
new WechatLoginRequest(
request.TenantId,
request.Code,
GetIpAddress(),
Request.Headers.UserAgent.ToString()),
cancellationToken);
return Ok(AuthenticatedUserDto.FromApplication(result));
}
[AllowAnonymous]
[HttpPost("refresh")]
[EndpointSummary("刷新登录会话")]
[EndpointDescription("使用 refresh token 轮换数据库 session并签发新的 access/refresh token。")]
public async Task<ActionResult<AuthTokenPair>> Refresh(
[FromBody] RefreshSessionDto request,
CancellationToken cancellationToken)
{
var result = await authService.RefreshAsync(
new RefreshSessionRequest(
request.RefreshToken,
GetIpAddress(),
Request.Headers.UserAgent.ToString()),
cancellationToken);
return Ok(result);
}
[AllowAnonymous]
[HttpPost("logout")]
[EndpointSummary("退出登录")]
[EndpointDescription("撤销 refresh token 对应的数据库 sessionsession 校验开启时,旧 access token 也会被拒绝。")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> Logout(
[FromBody] RefreshSessionDto request,
CancellationToken cancellationToken)
{
await authService.LogoutAsync(
new LogoutSessionRequest(request.RefreshToken),
cancellationToken);
return NoContent();
}
private string? GetIpAddress()
{
return HttpContext.Connection.RemoteIpAddress?.ToString();
}
}