Refactor authentication and streaming cookie handling: implement secure cookie logic based on environment in AuthEndpoints and StreamingEndpoints, enhance rate limiting policy in Program.cs, and update logging configuration in appsettings.json. Fix validation behavior to use asynchronous validation methods and improve error handling in frontend components.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using LiteCqrs;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using TeleWave.Api.Common;
|
||||
using TeleWave.Application.Auth;
|
||||
using TeleWave.Application.Auth.ChangePassword;
|
||||
@@ -62,6 +63,7 @@ public static class AuthEndpoints
|
||||
ISender sender,
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
IHostEnvironment env,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -70,10 +72,10 @@ public static class AuthEndpoints
|
||||
return result.ToHttpResult();
|
||||
|
||||
SetRefreshCookie(
|
||||
request,
|
||||
response,
|
||||
result.Value.RefreshToken,
|
||||
result.Value.RefreshTokenExpiresAt
|
||||
result.Value.RefreshTokenExpiresAt,
|
||||
UseSecureCookie(request, env)
|
||||
);
|
||||
return Results.Ok(ToLoginResponse(result.Value));
|
||||
}
|
||||
@@ -83,6 +85,7 @@ public static class AuthEndpoints
|
||||
ISender sender,
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
IHostEnvironment env,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -91,10 +94,10 @@ public static class AuthEndpoints
|
||||
return result.ToHttpResult();
|
||||
|
||||
SetRefreshCookie(
|
||||
request,
|
||||
response,
|
||||
result.Value.RefreshToken,
|
||||
result.Value.RefreshTokenExpiresAt
|
||||
result.Value.RefreshTokenExpiresAt,
|
||||
UseSecureCookie(request, env)
|
||||
);
|
||||
return Results.Ok(ToLoginResponse(result.Value));
|
||||
}
|
||||
@@ -103,6 +106,7 @@ public static class AuthEndpoints
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
ISender sender,
|
||||
IHostEnvironment env,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -112,18 +116,19 @@ public static class AuthEndpoints
|
||||
)
|
||||
return Results.Unauthorized();
|
||||
|
||||
var secure = UseSecureCookie(request, env);
|
||||
var result = await sender.Send(new RefreshCommand(rawToken), cancellationToken);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
response.Cookies.Delete(RefreshCookieName, BuildCookieOptions(request));
|
||||
response.Cookies.Delete(RefreshCookieName, BuildCookieOptions(secure));
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
SetRefreshCookie(
|
||||
request,
|
||||
response,
|
||||
result.Value.RefreshToken,
|
||||
result.Value.RefreshTokenExpiresAt
|
||||
result.Value.RefreshTokenExpiresAt,
|
||||
secure
|
||||
);
|
||||
return Results.Ok(ToLoginResponse(result.Value));
|
||||
}
|
||||
@@ -135,6 +140,7 @@ public static class AuthEndpoints
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
ISender sender,
|
||||
IHostEnvironment env,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
@@ -144,8 +150,9 @@ public static class AuthEndpoints
|
||||
)
|
||||
await sender.Send(new LogoutCommand(rawToken), cancellationToken);
|
||||
|
||||
response.Cookies.Delete(RefreshCookieName, BuildCookieOptions(request));
|
||||
DeleteStreamCookie(request, response);
|
||||
var secure = UseSecureCookie(request, env);
|
||||
response.Cookies.Delete(RefreshCookieName, BuildCookieOptions(secure));
|
||||
DeleteStreamCookie(response, secure);
|
||||
return Results.NoContent();
|
||||
}
|
||||
|
||||
@@ -179,45 +186,54 @@ public static class AuthEndpoints
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
ISender sender,
|
||||
IHostEnvironment env,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var result = await sender.Send(new DeleteMyAccountCommand(), cancellationToken);
|
||||
response.Cookies.Delete(RefreshCookieName, BuildCookieOptions(request));
|
||||
DeleteStreamCookie(request, response);
|
||||
var secure = UseSecureCookie(request, env);
|
||||
response.Cookies.Delete(RefreshCookieName, BuildCookieOptions(secure));
|
||||
DeleteStreamCookie(response, secure);
|
||||
return result.ToHttpResult();
|
||||
}
|
||||
|
||||
private static void SetRefreshCookie(
|
||||
HttpRequest request,
|
||||
HttpResponse response,
|
||||
string rawToken,
|
||||
DateTimeOffset expiresAt
|
||||
DateTimeOffset expiresAt,
|
||||
bool secure
|
||||
)
|
||||
{
|
||||
var options = BuildCookieOptions(request);
|
||||
var options = BuildCookieOptions(secure);
|
||||
options.Expires = expiresAt;
|
||||
response.Cookies.Append(RefreshCookieName, rawToken, options);
|
||||
}
|
||||
|
||||
private static CookieOptions BuildCookieOptions(HttpRequest request) =>
|
||||
private static CookieOptions BuildCookieOptions(bool secure) =>
|
||||
new()
|
||||
{
|
||||
HttpOnly = true,
|
||||
Secure = request.IsHttps,
|
||||
Secure = secure,
|
||||
SameSite = SameSiteMode.Strict,
|
||||
Path = "/api/auth",
|
||||
};
|
||||
|
||||
/// <summary>Ставить ли cookie с флагом Secure. Вне Development — всегда true: прод работает за
|
||||
/// внешним TLS-прокси, а <see cref="HttpRequest.IsHttps"/> ненадёжен (при неполной настройке
|
||||
/// ForwardedHeaders он false, и долгоживущий refresh-cookie ушёл бы без Secure). В Development
|
||||
/// допускаем HTTP-разработку.</summary>
|
||||
private static bool UseSecureCookie(HttpRequest request, IHostEnvironment env) =>
|
||||
!env.IsDevelopment() || request.IsHttps;
|
||||
|
||||
/// <summary>Гасит stream-cookie (tw_stream, Path=/api) — иначе после выхода эфир можно смотреть
|
||||
/// по прямой ссылке ещё до истечения токена.</summary>
|
||||
private static void DeleteStreamCookie(HttpRequest request, HttpResponse response) =>
|
||||
private static void DeleteStreamCookie(HttpResponse response, bool secure) =>
|
||||
response.Cookies.Delete(
|
||||
"tw_stream",
|
||||
new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
Secure = request.IsHttps,
|
||||
Secure = secure,
|
||||
SameSite = SameSiteMode.Strict,
|
||||
Path = "/api",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user