自建登录验证码

This commit is contained in:
biss committed 2026-09-12 08:17:14 +08:00
1 parent 149eb66890
commit 564ffecfed
9 files changed
+75 -49

No files matched your search

+9 -10
View File
@@ -4,7 +4,7 @@ using Jiaowu.Api.Domain.Academic;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Jiaowu.Api.Infrastructure.Caching;
using Lazy.Captcha.Core;
using CaptchaKit.AspNetCore;
using Jiaowu.Api.Infrastructure.Persistence;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
@@ -21,7 +21,7 @@ public sealed class AuthController(
UserManager<ApplicationUser> userManager,
IAuthSessionService authSessionService,
ITwoFactorLoginTicketService twoFactorTickets,
ICaptcha captcha,
ICaptchaKitService captcha,
IAppCache cache) : ControllerBase
{
[AllowAnonymous]
@@ -140,13 +140,12 @@ public sealed class AuthController(
[AllowAnonymous]
[EnableRateLimiting("public-auth")]
[HttpPost("login/captcha")]
public ActionResult<LazyLoginCaptchaResponse> CreateLoginCaptcha()
public async Task<ActionResult<LoginCaptchaResponse>> CreateLoginCaptcha(CancellationToken cancellationToken)
{
var captchaId = Guid.NewGuid().ToString("N");
var generated = captcha.Generate(captchaId, expirySeconds: 120);
return Ok(new LazyLoginCaptchaResponse(
captchaId,
$"data:image/gif;base64,{Convert.ToBase64String(generated.Bytes)}"));
var generated = await captcha.CreateAsync(cancellationToken);
return Ok(new LoginCaptchaResponse(
generated.Id,
$"data:{generated.ContentType};base64,{Convert.ToBase64String(generated.ImageBytes)}"));
}
[AllowAnonymous]
@@ -156,7 +155,7 @@ public sealed class AuthController(
LoginRequest request,
CancellationToken cancellationToken)
{
if (!captcha.Validate(request.CaptchaId, request.CaptchaCode))
if (!await captcha.VerifyAsync(request.CaptchaId, request.CaptchaCode, cancellationToken))
return Unauthorized(LoginCaptchaProblem());
var user = await userManager.FindByNameAsync(request.UserName);
if (user is null || !user.IsEnabled)
@@ -334,7 +333,7 @@ public sealed record LoginRequest(
[Required, MinLength(3), MaxLength(16)] string CaptchaCode,
bool IsNativeApp = false);
public sealed record LazyLoginCaptchaResponse(string CaptchaId, string ImageData);
public sealed record LoginCaptchaResponse(string CaptchaId, string ImageData);
public sealed record TotpLoginRequest(
[Required, MinLength(20), MaxLength(2048)] string TwoFactorTicket,
+3 -3
View File
@@ -12,7 +12,7 @@ using Microsoft.AspNetCore.RateLimiting;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using Lazy.Captcha.Core;
using CaptchaKit.AspNetCore;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Jiaowu.Api.Controllers;
@@ -23,7 +23,7 @@ public sealed class SsoController(
UserManager<ApplicationUser> userManager,
IAuthSessionService authSessionService,
IDistributedCache cache,
ICaptcha captcha,
ICaptchaKitService captcha,
IOptions<SsoOptions> options,
ILogger<SsoController> logger) : ControllerBase
{
@@ -59,7 +59,7 @@ public sealed class SsoController(
if (string.IsNullOrWhiteSpace(bindingIntent) &&
(string.IsNullOrWhiteSpace(captchaId) ||
string.IsNullOrWhiteSpace(captchaCode) ||
!captcha.Validate(captchaId, captchaCode)))
!await captcha.VerifyAsync(captchaId, captchaCode, cancellationToken)))
{
return Unauthorized(AuthController.LoginCaptchaProblem());
}
+4 -1
View File
@@ -28,7 +28,6 @@
<PackageReference Include="ClosedXML" Version="0.105.1" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.5.1" />
<PackageReference Include="Fido2" Version="4.0.1" />
<PackageReference Include="Lazy.Captcha.Core" Version="2.2.4" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.11" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.11" />
@@ -48,6 +47,10 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.2.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\packages\CaptchaKit\src\CaptchaKit.AspNetCore\CaptchaKit.AspNetCore.csproj" />
</ItemGroup>
<Target Name="BuildVueFrontendForPublish" AfterTargets="ComputeFilesToPublish" Condition="Exists('$(SpaRoot)/package.json')">
<Message Condition="'$(BuildFrontendOnPublish)' == 'true'" Importance="high" Text="Building Vue frontend for ASP.NET Core publish..." />
<Exec Condition="'$(BuildFrontendOnPublish)' == 'true'" WorkingDirectory="$(SpaRoot)" Command="$(NpmCommand) ci" />
Loaded 3 of 9 files, more files were not shown because too many files have changed in this diff. Show more