forked from AcaMate/AcaMate_Web
1. 쿠키만 사용하던 저장 동작을 다른 저장소도 사용하게 변경 1.1. 쿠키 대신 세션 레포지토리를 기본적으로 사용하게 Service 코드 구현 2. 로그인 되었을 경우 화면 표기 변경 2.1. 시작하기 버튼 hidden 처리 2.2. 사용자 이름 불러오기 2.3. 로그인 동작 관련 변수 스토리지 저장 2.4. 서버에서 직접적인 크라이언트 쿠키 저장이 아닌 서버는 뒤의 값으로 간섭하게 변경
120 lines
3.8 KiB
C#
120 lines
3.8 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Microsoft.JSInterop;
|
|
using System.Text.Json;
|
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
|
|
|
namespace Front.Program.Services;
|
|
|
|
public class SecureService
|
|
{
|
|
private readonly ILogger<SecureService> _logger;
|
|
private readonly IJSRuntime _jsRuntime;
|
|
private readonly IWebAssemblyHostEnvironment _environment;
|
|
private string? _key;
|
|
private string? _iv;
|
|
private Task? _initializationTask;
|
|
|
|
public SecureService(
|
|
ILogger<SecureService> logger,
|
|
IJSRuntime jsRuntime,
|
|
IWebAssemblyHostEnvironment environment)
|
|
{
|
|
_logger = logger;
|
|
_jsRuntime = jsRuntime;
|
|
_environment = environment;
|
|
_initializationTask = InitializeAsync();
|
|
}
|
|
|
|
private async Task InitializeAsync()
|
|
{
|
|
try
|
|
{
|
|
var configFile = $"appsettings.{_environment.Environment}.json";
|
|
_logger.LogInformation($"설정 파일 로드: {configFile}");
|
|
|
|
var config = await _jsRuntime.InvokeAsync<JsonElement>("loadConfig", configFile);
|
|
if (config.ValueKind == JsonValueKind.Null)
|
|
{
|
|
throw new InvalidOperationException($"설정 파일을 로드할 수 없습니다: {configFile}");
|
|
}
|
|
|
|
var security = config.GetProperty("Security");
|
|
_key = security.GetProperty("EncryptionKey").GetString()
|
|
?? throw new ArgumentNullException("Security:EncryptionKey");
|
|
_iv = security.GetProperty("EncryptionIV").GetString()
|
|
?? throw new ArgumentNullException("Security:EncryptionIV");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"설정 로드 중 오류 발생: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private async Task EnsureInitializedAsync()
|
|
{
|
|
if (_initializationTask != null)
|
|
{
|
|
await _initializationTask;
|
|
_initializationTask = null;
|
|
}
|
|
}
|
|
|
|
private byte[] GetKeyBytes(string key)
|
|
{
|
|
using (var sha256 = SHA256.Create())
|
|
{
|
|
return sha256.ComputeHash(Encoding.UTF8.GetBytes(key));
|
|
}
|
|
}
|
|
|
|
private byte[] GetIVBytes(string iv)
|
|
{
|
|
using (var sha256 = SHA256.Create())
|
|
{
|
|
var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(iv));
|
|
return hash.Take(16).ToArray(); // IV는 16바이트만 필요
|
|
}
|
|
}
|
|
|
|
public async Task<string> EncryptAsync(string plainText)
|
|
{
|
|
await EnsureInitializedAsync();
|
|
|
|
if (_key == null || _iv == null)
|
|
throw new InvalidOperationException("암호화 키가 초기화되지 않았습니다.");
|
|
|
|
try
|
|
{
|
|
return await _jsRuntime.InvokeAsync<string>("encryptText", plainText, _key, _iv);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"암호화 중 오류 발생: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<string> DecryptAsync(string cipherText)
|
|
{
|
|
await EnsureInitializedAsync();
|
|
|
|
if (_key == null || _iv == null)
|
|
throw new InvalidOperationException("암호화 키가 초기화되지 않았습니다.");
|
|
|
|
try
|
|
{
|
|
return await _jsRuntime.InvokeAsync<string>("decryptText", cipherText, _key, _iv);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError($"복호화 중 오류 발생: {ex.Message}");
|
|
throw;
|
|
}
|
|
}
|
|
|
|
// 동기 메서드는 비동기 메서드를 호출하도록 수정
|
|
public string Encrypt(string plainText) => EncryptAsync(plainText).GetAwaiter().GetResult();
|
|
public string Decrypt(string cipherText) => DecryptAsync(cipherText).GetAwaiter().GetResult();
|
|
} |