diff --git a/TVTComment/Model/ChatCollectService/NiconicoLiveChatCollectService.cs b/TVTComment/Model/ChatCollectService/NiconicoLiveChatCollectService.cs
index ed78816..dca9fac 100644
--- a/TVTComment/Model/ChatCollectService/NiconicoLiveChatCollectService.cs
+++ b/TVTComment/Model/ChatCollectService/NiconicoLiveChatCollectService.cs
@@ -48,6 +48,7 @@ protected ChatReceivingException(
private readonly NiconicoUtils.NicoLiveCommentSender commentSender;
private DateTime lastHeartbeatTime = DateTime.MinValue;
private readonly CancellationTokenSource cancel = new CancellationTokenSource();
+ private NiconicoUtils.NiconicoLoginSession session;
public NiconicoLiveChatCollectService(
ChatCollectServiceEntry.IChatCollectServiceEntry serviceEntry, string liveId,
@@ -56,6 +57,7 @@ NiconicoUtils.NiconicoLoginSession session
{
this.ServiceEntry = serviceEntry;
this.originalLiveId = liveId;
+ this.session = session;
var assembly = Assembly.GetExecutingAssembly().GetName();
var ua = assembly.Name + "/" + assembly.Version.ToString(3);
@@ -131,6 +133,8 @@ private async Task collectChat(CancellationToken cancel)
}
catch (HttpRequestException e)
{
+ if (e.StatusCode == System.Net.HttpStatusCode.Unauthorized)
+ this.session.BadSession = true;
throw new ChatReceivingException("サーバーとの通信でエラーが発生しました", e);
}
var playerStatus = await JsonDocument.ParseAsync(playerStatusStr, cancellationToken: cancel).ConfigureAwait(false);
diff --git a/TVTComment/Model/ChatService/NiconicoChatService.cs b/TVTComment/Model/ChatService/NiconicoChatService.cs
index 83b33ac..ea06ecd 100644
--- a/TVTComment/Model/ChatService/NiconicoChatService.cs
+++ b/TVTComment/Model/ChatService/NiconicoChatService.cs
@@ -10,6 +10,10 @@ class NiconicoChatServiceSettings
{
public string UserId { get; set; } = "";
public string Password { get; set; } = "";
+ // ログインセッションを保持する
+ public string NicoSid { get; set; } = "";
+ public string Session { get; set; } = "";
+ public string SessionSecure { get; set; } = "";
}
class NiconicoChatService : IChatService
@@ -35,6 +39,18 @@ public string UserPassword
get { return this.settings.Password; }
}
public bool IsLoggedin { get; private set; }
+ public string NicoSid
+ {
+ get { return this.settings.NicoSid; }
+ }
+ public string Session
+ {
+ get { return this.settings.Session; }
+ }
+ public string SessionSecure
+ {
+ get { return this.settings.SessionSecure; }
+ }
public NiconicoChatService(
NiconicoChatServiceSettings settings, ChannelDatabase channelDatabase,
@@ -48,7 +64,7 @@ public NiconicoChatService(
try
{
if(!string.IsNullOrWhiteSpace(UserId) && !string.IsNullOrWhiteSpace(UserPassword))
- SetUser(UserId, UserPassword).Wait();
+ SetUser(UserId, UserPassword, NicoSid, Session, SessionSecure).Wait();
}
catch (AggregateException e)
when (e.InnerExceptions.Count == 1 && e.InnerExceptions[0] is NiconicoUtils.NiconicoLoginSessionException)
@@ -68,9 +84,12 @@ public NiconicoChatService(
///
/// ニコニコのユーザーID
/// ニコニコのパスワード
+ /// ログインセッション(nicosid)
+ /// ログインセッション(user_session)
+ /// ログインセッション(user_session_secure)
/// またはがnull若しくはホワイトスペースだった時
/// ログインに失敗した時
- public async Task SetUser(string userId, string userPassword)
+ public async Task SetUser(string userId, string userPassword, string nicoSid, string session, string sessionSecure)
{
if (string.IsNullOrWhiteSpace(userId))
throw new ArgumentException($"{nameof(userId)} must not be null nor white space", nameof(userId));
@@ -78,13 +97,16 @@ public async Task SetUser(string userId, string userPassword)
throw new ArgumentException($"{nameof(userPassword)} must not be null nor white space", nameof(userPassword));
//ログインしてみる
- var tmpSession = new NiconicoUtils.NiconicoLoginSession(userId, userPassword);
+ var tmpSession = new NiconicoUtils.NiconicoLoginSession(userId, userPassword, nicoSid, session, sessionSecure);
await tmpSession.Login().ConfigureAwait(false);
//成功したら設定、セッションを置き換える
this.IsLoggedin = true;
this.settings.UserId = userId;
this.settings.Password = userPassword;
+ this.settings.NicoSid = tmpSession.nicosid;
+ this.settings.Session = tmpSession.session;
+ this.settings.SessionSecure = tmpSession.secure;
try
{
await (this.loginSession.Value?.Logout() ?? Task.CompletedTask);
diff --git a/TVTComment/Model/NiconicoUtils/NiconicoLoginSession.cs b/TVTComment/Model/NiconicoUtils/NiconicoLoginSession.cs
index 1145b94..51fffb7 100644
--- a/TVTComment/Model/NiconicoUtils/NiconicoLoginSession.cs
+++ b/TVTComment/Model/NiconicoUtils/NiconicoLoginSession.cs
@@ -42,8 +42,12 @@ class NiconicoLoginSession
{
private string mail;
private string password;
+ public string nicosid { get; private set; }
+ public string session { get; private set; }
+ public string secure { get; private set; }
private CookieCollection cookie = null;
+ public bool BadSession = false;
public bool IsLoggedin => cookie != null;
///
/// 送信するべき認証情報を含んだクッキー
@@ -60,10 +64,13 @@ public CookieCollection Cookie
}
}
- public NiconicoLoginSession(string mail, string password)
+ public NiconicoLoginSession(string mail, string password, string nicosid, string session, string secure)
{
this.mail = mail;
this.password = password;
+ this.nicosid = nicosid;
+ this.session = session;
+ this.secure = secure;
}
///
@@ -74,9 +81,20 @@ public NiconicoLoginSession(string mail, string password)
///
public async Task Login()
{
- if (this.IsLoggedin)
+ if (!this.BadSession && this.IsLoggedin)
throw new InvalidOperationException("すでにログインしています");
+ if (!this.BadSession && nicosid != null && nicosid.Length > 0 && session != null && session.Length > 0 && secure != null && secure.Length > 0)
+ {
+ this.cookie = new CookieCollection();
+
+ this.cookie.Add(new Cookie("nicosid", nicosid, "/", "nicovideo.jp"));
+ this.cookie.Add(new Cookie("user_session", session, "/", "nicovideo.jp"));
+ this.cookie.Add(new Cookie("user_session_secure", secure, "/", "nicovideo.jp"));
+
+ return;
+ }
+
const string loginUrl = "https://secure.nicovideo.jp/secure/login?site=niconico";
var handler = new HttpClientHandler();
@@ -102,6 +120,16 @@ public async Task Login()
if (cookieCollection.All(x => x.Name != "user_session"))
throw new LoginFailureNiconicoLoginSessionException();
+ Cookie cookieNicosid = cookieCollection.Where(x => x.Name == "nicosid").Single();
+ Cookie cookieSession = cookieCollection.Where(x => x.Name == "user_session").Single();
+ Cookie cookieSecure = cookieCollection.Where(x => x.Name == "user_session_secure").Single();
+
+ this.nicosid = cookieNicosid.Value;
+ this.session = cookieSession.Value;
+ this.secure = cookieSecure.Value;
+
+ this.BadSession = false;
+
this.cookie = cookieCollection;
}
@@ -128,6 +156,9 @@ public async Task Logout()
throw new NetworkNiconicoLoginSessionException(e);
}
this.cookie = null;
+ this.nicosid = null;
+ this.session = null;
+ this.secure = null;
}
}
}
diff --git a/TVTComment/ViewModels/SettingsWindowViewModel.cs b/TVTComment/ViewModels/SettingsWindowViewModel.cs
index 79d3b64..48641cb 100644
--- a/TVTComment/ViewModels/SettingsWindowViewModel.cs
+++ b/TVTComment/ViewModels/SettingsWindowViewModel.cs
@@ -15,6 +15,9 @@ class SettingsWindowViewModel : BindableBase
public ObservableValue NiconicoLoginStatus { get; } = new ObservableValue();
public ObservableValue NiconicoUserId { get; } = new ObservableValue();
public ObservableValue NiconicoPassword { get; } = new ObservableValue();
+ public ObservableValue NiconicoSid { get; } = new ObservableValue();
+ public ObservableValue NiconicoSession { get; } = new ObservableValue();
+ public ObservableValue NiconicoSecure { get; } = new ObservableValue();
public ObservableValue NichanResCollectInterval { get; } = new ObservableValue();
public ObservableValue NichanThreadSearchInterval { get; } = new ObservableValue();
public ObservableValue NichanApiHmKey { get; } = new ObservableValue();
@@ -52,7 +55,7 @@ public SettingsWindowViewModel(Model.TVTComment model)
try
{
- await niconico.SetUser(NiconicoUserId.Value, NiconicoPassword.Value);
+ await niconico.SetUser(NiconicoUserId.Value, NiconicoPassword.Value, NiconicoSid.Value, NiconicoSession.Value, NiconicoSecure.Value);
syncNiconicoUserStatus();
}
catch (Model.NiconicoUtils.NiconicoLoginSessionException)
@@ -97,6 +100,9 @@ private void syncNiconicoUserStatus()
NiconicoLoginStatus.Value = niconico.IsLoggedin ? "ログイン済" : "未ログイン";
NiconicoUserId.Value = niconico.UserId;
NiconicoPassword.Value = niconico.UserPassword;
+ NiconicoSid.Value = niconico.NicoSid;
+ NiconicoSession.Value = niconico.Session;
+ NiconicoSecure.Value = niconico.SessionSecure;
}
private void syncNichanSettings()