Доработана QR авторизация

This commit is contained in:
FrigaT
2026-04-20 16:06:47 +03:00
parent 12241639dc
commit 9c95e6b189
11 changed files with 784 additions and 45 deletions

View File

@@ -1,9 +1,9 @@
using PlaylistShared.Api.Data;
using Microsoft.EntityFrameworkCore;
using PlaylistShared.Api.Data;
using PlaylistShared.Api.Entities;
using PlaylistShared.Shared.Yandex;
using System.Net;
using System.Text.Json;
using YandexMusic.API.Models.Account;
namespace PlaylistShared.Api.Services;
@@ -20,12 +20,33 @@ public class YandexAuthService
_dbContext = dbContext;
}
internal async Task<YandexAuthQr> GetQrOrGenerate(ApplicationUser user)
{
var existingSession = _dbContext.YandexAuthSessions
.Where(s => s.UserId == user.Id && !s.IsConfirmed && s.CreatedAt > DateTime.UtcNow.AddMinutes(-5))
.OrderByDescending(s => s.CreatedAt)
.FirstOrDefault();
if (existingSession != null)
{
return new YandexAuthQr
{
QrLink = existingSession.QrCodeUrl,
SessionId = existingSession.Id.ToString()
};
}
return await GenerateQrAsync(user);
}
internal async Task<YandexAuthQr> GenerateQrAsync(ApplicationUser user)
{
var client = _apiService.Client;
var qr = await client.GetAuthQRLink();
var trackId = client.AuthStorage.AuthToken.TrackId;
var csfrToken = client.AuthStorage.AuthToken.CsfrToken;
var headerProcessUuid = client.AuthStorage.HeaderToken.ProcessUuid;
var headerCsfrToken = client.AuthStorage.HeaderToken.CsfrToken;
if (string.IsNullOrEmpty(qr))
throw new Exception("Не удалось получить QR-ссылку");
@@ -41,6 +62,8 @@ public class YandexAuthService
IsConfirmed = false,
TrackId = trackId,
CsfrToken = csfrToken,
HeaderCsfrToken = headerCsfrToken,
HeaderProcessId = headerProcessUuid,
};
@@ -67,19 +90,26 @@ public class YandexAuthService
_apiService.Client.AuthStorage.AuthToken.CsfrToken = session?.CsfrToken ?? "";
_apiService.Client.AuthStorage.AuthToken.TrackId = session?.TrackId ?? "";
_apiService.Client.AuthStorage.HeaderToken.CsfrToken = session?.HeaderCsfrToken ?? "";
_apiService.Client.AuthStorage.HeaderToken.ProcessUuid = session?.HeaderProcessId ?? "";
var status = await _apiService.Client.AuthorizeByQR();
var status = await _apiService.Client.CheckQRStatusAsync();
if (status?.Status == YAuthStatus.Ok)
if (status?.State == "otp_auth_finished")
{
session.ConfirmedAt = DateTime.UtcNow;
session.IsConfirmed = true;
await _dbContext.SaveChangesAsync();
return new()
try
{
Status = Shared.Enums.YandexAuthQrStatus.Authorized,
};
var auth = await _apiService.Client.AuthorizeByQR();
}
catch (Exception ex)
{
return new() { Status = Shared.Enums.YandexAuthQrStatus.Error, };
}
_dbContext.YandexAuthSessions.Where(t => t.UserId == session.UserId).ExecuteDelete();
_dbContext.SaveChanges();
return new() { Status = Shared.Enums.YandexAuthQrStatus.Authorized, };
}
return new()
@@ -91,7 +121,6 @@ public class YandexAuthService
private string SerializeCookies(CookieContainer container)
{
var domains = new[] { "yandex.ru", "passport.yandex.ru", ".yandex.ru" };
var allCookies = new List<object>();
var cookies = container.GetAllCookies();
@@ -108,8 +137,7 @@ public class YandexAuthService
var cookies = JsonSerializer.Deserialize<List<CookieData>>(serializedCookies);
foreach (var c in cookies)
{
var uri = new Uri($"{c.Domain}");
container.Add(uri, new Cookie(c.Name, c.Value, c.Path, c.Domain));
container.Add(new Cookie(c.Name, c.Value, c.Path, c.Domain));
}
}