Добавлен вывод QR яндекса

This commit is contained in:
FrigaT
2026-04-19 21:06:36 +03:00
parent 4324b86512
commit 12241639dc
21 changed files with 1349 additions and 46 deletions

View File

@@ -0,0 +1,123 @@
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;
public class YandexAuthService
{
private readonly YandexApiService _apiService;
private readonly ApplicationDbContext _dbContext;
public YandexApiService Service => _apiService;
public YandexAuthService(YandexApiService apiService, ApplicationDbContext dbContext)
{
_apiService = apiService;
_dbContext = dbContext;
}
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;
if (string.IsNullOrEmpty(qr))
throw new Exception("Не удалось получить QR-ссылку");
var cookiesJson = SerializeCookies(_apiService.CookieContainer);
var session = new YandexAuthSession
{
UserId = user.Id,
QrCodeUrl = qr,
SerializedCookies = cookiesJson,
CreatedAt = DateTime.UtcNow,
IsConfirmed = false,
TrackId = trackId,
CsfrToken = csfrToken,
};
_dbContext.YandexAuthSessions.Add(session);
await _dbContext.SaveChangesAsync();
return new YandexAuthQr
{
QrLink = qr,
SessionId = session.Id.ToString()
};
}
internal async Task<YandexAuthQrCheck?> CheckQrAsync(int sessionId)
{
var session = await _dbContext.YandexAuthSessions.FindAsync(sessionId);
if (session == null) return null;
RestoreCookies(_apiService.CookieContainer, session.SerializedCookies);
if (_apiService.Client.AuthStorage.AuthToken is null)
{
_apiService.Client.AuthStorage.AuthToken = new();
}
_apiService.Client.AuthStorage.AuthToken.CsfrToken = session?.CsfrToken ?? "";
_apiService.Client.AuthStorage.AuthToken.TrackId = session?.TrackId ?? "";
var status = await _apiService.Client.AuthorizeByQR();
if (status?.Status == YAuthStatus.Ok)
{
session.ConfirmedAt = DateTime.UtcNow;
session.IsConfirmed = true;
await _dbContext.SaveChangesAsync();
return new()
{
Status = Shared.Enums.YandexAuthQrStatus.Authorized,
};
}
return new()
{
Status = Shared.Enums.YandexAuthQrStatus.Pending,
};
}
private string SerializeCookies(CookieContainer container)
{
var domains = new[] { "yandex.ru", "passport.yandex.ru", ".yandex.ru" };
var allCookies = new List<object>();
var cookies = container.GetAllCookies();
foreach (Cookie cookie in cookies)
{
allCookies.Add(new { cookie.Name, cookie.Value, cookie.Domain, cookie.Path });
}
return JsonSerializer.Serialize(allCookies);
}
private void RestoreCookies(CookieContainer container, string serializedCookies)
{
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));
}
}
private class CookieData
{
public string Name { get; set; }
public string Value { get; set; }
public string Domain { get; set; }
public string Path { get; set; }
}
}