自建登录验证码
This commit is contained in:
1 parent
149eb66890
commit
564ffecfed
9 files changed
+75
-49
No files matched your search
+3
-1
@@ -3,6 +3,8 @@
|
|||||||
**/node_modules/
|
**/node_modules/
|
||||||
**/dist/
|
**/dist/
|
||||||
.artifacts/
|
.artifacts/
|
||||||
|
.codex-build/
|
||||||
|
packages/CaptchaKit/artifacts/
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/
|
.vscode/
|
||||||
*.user
|
*.user
|
||||||
@@ -17,4 +19,4 @@ src/Jiaowu.Api/wwwroot/
|
|||||||
!.env.example
|
!.env.example
|
||||||
!.env.docker.example
|
!.env.docker.example
|
||||||
certs/
|
certs/
|
||||||
publish/
|
publish/
|
||||||
@@ -4,7 +4,7 @@ using Jiaowu.Api.Domain.Academic;
|
|||||||
using Jiaowu.Api.Domain.Identity;
|
using Jiaowu.Api.Domain.Identity;
|
||||||
using Jiaowu.Api.Infrastructure.Auth;
|
using Jiaowu.Api.Infrastructure.Auth;
|
||||||
using Jiaowu.Api.Infrastructure.Caching;
|
using Jiaowu.Api.Infrastructure.Caching;
|
||||||
using Lazy.Captcha.Core;
|
using CaptchaKit.AspNetCore;
|
||||||
using Jiaowu.Api.Infrastructure.Persistence;
|
using Jiaowu.Api.Infrastructure.Persistence;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
@@ -21,7 +21,7 @@ public sealed class AuthController(
|
|||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
IAuthSessionService authSessionService,
|
IAuthSessionService authSessionService,
|
||||||
ITwoFactorLoginTicketService twoFactorTickets,
|
ITwoFactorLoginTicketService twoFactorTickets,
|
||||||
ICaptcha captcha,
|
ICaptchaKitService captcha,
|
||||||
IAppCache cache) : ControllerBase
|
IAppCache cache) : ControllerBase
|
||||||
{
|
{
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
@@ -140,13 +140,12 @@ public sealed class AuthController(
|
|||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[EnableRateLimiting("public-auth")]
|
[EnableRateLimiting("public-auth")]
|
||||||
[HttpPost("login/captcha")]
|
[HttpPost("login/captcha")]
|
||||||
public ActionResult<LazyLoginCaptchaResponse> CreateLoginCaptcha()
|
public async Task<ActionResult<LoginCaptchaResponse>> CreateLoginCaptcha(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var captchaId = Guid.NewGuid().ToString("N");
|
var generated = await captcha.CreateAsync(cancellationToken);
|
||||||
var generated = captcha.Generate(captchaId, expirySeconds: 120);
|
return Ok(new LoginCaptchaResponse(
|
||||||
return Ok(new LazyLoginCaptchaResponse(
|
generated.Id,
|
||||||
captchaId,
|
$"data:{generated.ContentType};base64,{Convert.ToBase64String(generated.ImageBytes)}"));
|
||||||
$"data:image/gif;base64,{Convert.ToBase64String(generated.Bytes)}"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
@@ -156,7 +155,7 @@ public sealed class AuthController(
|
|||||||
LoginRequest request,
|
LoginRequest request,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (!captcha.Validate(request.CaptchaId, request.CaptchaCode))
|
if (!await captcha.VerifyAsync(request.CaptchaId, request.CaptchaCode, cancellationToken))
|
||||||
return Unauthorized(LoginCaptchaProblem());
|
return Unauthorized(LoginCaptchaProblem());
|
||||||
var user = await userManager.FindByNameAsync(request.UserName);
|
var user = await userManager.FindByNameAsync(request.UserName);
|
||||||
if (user is null || !user.IsEnabled)
|
if (user is null || !user.IsEnabled)
|
||||||
@@ -334,7 +333,7 @@ public sealed record LoginRequest(
|
|||||||
[Required, MinLength(3), MaxLength(16)] string CaptchaCode,
|
[Required, MinLength(3), MaxLength(16)] string CaptchaCode,
|
||||||
bool IsNativeApp = false);
|
bool IsNativeApp = false);
|
||||||
|
|
||||||
public sealed record LazyLoginCaptchaResponse(string CaptchaId, string ImageData);
|
public sealed record LoginCaptchaResponse(string CaptchaId, string ImageData);
|
||||||
|
|
||||||
public sealed record TotpLoginRequest(
|
public sealed record TotpLoginRequest(
|
||||||
[Required, MinLength(20), MaxLength(2048)] string TwoFactorTicket,
|
[Required, MinLength(20), MaxLength(2048)] string TwoFactorTicket,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using Microsoft.AspNetCore.RateLimiting;
|
|||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Microsoft.Extensions.Caching.Distributed;
|
using Microsoft.Extensions.Caching.Distributed;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Lazy.Captcha.Core;
|
using CaptchaKit.AspNetCore;
|
||||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||||
|
|
||||||
namespace Jiaowu.Api.Controllers;
|
namespace Jiaowu.Api.Controllers;
|
||||||
@@ -23,7 +23,7 @@ public sealed class SsoController(
|
|||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
IAuthSessionService authSessionService,
|
IAuthSessionService authSessionService,
|
||||||
IDistributedCache cache,
|
IDistributedCache cache,
|
||||||
ICaptcha captcha,
|
ICaptchaKitService captcha,
|
||||||
IOptions<SsoOptions> options,
|
IOptions<SsoOptions> options,
|
||||||
ILogger<SsoController> logger) : ControllerBase
|
ILogger<SsoController> logger) : ControllerBase
|
||||||
{
|
{
|
||||||
@@ -59,7 +59,7 @@ public sealed class SsoController(
|
|||||||
if (string.IsNullOrWhiteSpace(bindingIntent) &&
|
if (string.IsNullOrWhiteSpace(bindingIntent) &&
|
||||||
(string.IsNullOrWhiteSpace(captchaId) ||
|
(string.IsNullOrWhiteSpace(captchaId) ||
|
||||||
string.IsNullOrWhiteSpace(captchaCode) ||
|
string.IsNullOrWhiteSpace(captchaCode) ||
|
||||||
!captcha.Validate(captchaId, captchaCode)))
|
!await captcha.VerifyAsync(captchaId, captchaCode, cancellationToken)))
|
||||||
{
|
{
|
||||||
return Unauthorized(AuthController.LoginCaptchaProblem());
|
return Unauthorized(AuthController.LoginCaptchaProblem());
|
||||||
}
|
}
|
||||||
|
|||||||
Loaded 3 of 9 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user