주기적인 인증 기능 포함 및 코드 정리
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
using FluentScheduler;
|
||||
using System.ComponentModel;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace BaronSoftware.SSO
|
||||
{
|
||||
/// <summary>
|
||||
@@ -7,6 +12,7 @@ namespace BaronSoftware.SSO
|
||||
{
|
||||
private readonly SsoClient client;
|
||||
private readonly BaronSSOOption option;
|
||||
private Schedule licenseCheckScheduler;
|
||||
|
||||
public UserInfo CurrentUser { get; private set; }
|
||||
|
||||
@@ -76,13 +82,13 @@ namespace BaronSoftware.SSO
|
||||
/// UI 스레드에서 <c>.Wait()</c>/<c>.Result</c> 로 블로킹하면 데드락입니다. 자세한 이유는
|
||||
/// <see cref="SignInAsync()"/> 의 설명을 참고하세요. (UI 스레드면 await, 동기 호출은 <see cref="SignIn"/>)
|
||||
/// </remarks>
|
||||
public async Task SignInAsync(string refreshToken)
|
||||
public async Task SignInAsync(string refreshToken, bool retryWindow = true)
|
||||
{
|
||||
UserInfo user = null;
|
||||
var isConnected = await CheckConnection();
|
||||
if (isConnected)
|
||||
{
|
||||
var token = await client.LoginAsync(refreshToken);
|
||||
var token = await client.LoginAsync(refreshToken, retryWindow);
|
||||
var userJson = await client.GetUserInfoAsync(token.AccessToken);
|
||||
if (string.IsNullOrEmpty(userJson))
|
||||
throw new InvalidOperationException($"Failed to get userinfo : {token.ToString()}");
|
||||
@@ -98,7 +104,7 @@ namespace BaronSoftware.SSO
|
||||
|
||||
user = UserInfo.FromSsoFile();
|
||||
if (user == null)
|
||||
throw new InvalidUserException("Not found sso data for offline.");
|
||||
throw new InvalidUserException("Offline mode. Not found sso data for offline.");
|
||||
}
|
||||
|
||||
// 가족사가 아니고, 인증도 실패 시
|
||||
@@ -109,8 +115,12 @@ namespace BaronSoftware.SSO
|
||||
|
||||
CurrentUser = user;
|
||||
CurrentUser.Save();
|
||||
|
||||
RunLicenseInterval();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 로그아웃: 현재 사용자 정보 + 저장된 refresh_token + WebView SSO 세션 쿠키를 모두 삭제합니다.
|
||||
/// 세션 쿠키까지 지우므로 다음 로그인 시 로그인 창이 다시 표시됩니다.
|
||||
@@ -140,11 +150,59 @@ namespace BaronSoftware.SSO
|
||||
await client.GetDiscoveryAsync();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
catch(Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RunLicenseInterval()
|
||||
{
|
||||
if (licenseCheckScheduler != null)
|
||||
return;
|
||||
|
||||
licenseCheckScheduler = new Schedule(async () =>
|
||||
{
|
||||
// 오프라인의 경우 주기적인 인증을 무시한다.
|
||||
// 단, 언제든 온라인 상태가 될 수 있으니 주기 인증을 멈추지는 않는다.
|
||||
var isOnline = await CheckConnection();
|
||||
if (!isOnline)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await SignInAsync(CurrentUser.RefreshToken, false);
|
||||
}
|
||||
catch(HttpRequestException)
|
||||
{
|
||||
//네트워크 오류는 무시한다.
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
StopLicenseInterval();
|
||||
await SignOutAsync();
|
||||
option.ExpiredToken?.Invoke();
|
||||
}
|
||||
}, run => run.Every(option.LicenseCheckInterval).Seconds()
|
||||
);
|
||||
|
||||
licenseCheckScheduler.Start();
|
||||
}
|
||||
|
||||
public void StopLicenseInterval()
|
||||
{
|
||||
if (licenseCheckScheduler == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
licenseCheckScheduler.Stop();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
licenseCheckScheduler = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user