Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ニコニコ動画のログインセッションを設定ファイルに保持 #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
28 changes: 25 additions & 3 deletions TVTComment/Model/ChatService/NiconicoChatService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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)
Expand All @@ -68,23 +84,29 @@ public NiconicoChatService(
/// </summary>
/// <param name="userId">ニコニコのユーザーID</param>
/// <param name="userPassword">ニコニコのパスワード</param>
/// <param name="nicoSid">ログインセッション(nicosid)</param>
/// <param name="session">ログインセッション(user_session)</param>
/// <param name="sessionSecure">ログインセッション(user_session_secure)</param>
/// <exception cref="ArgumentException"><paramref name="userId"/>または<paramref name="userPassword"/>がnull若しくはホワイトスペースだった時</exception>
/// <exception cref="NiconicoUtils.NiconicoLoginSessionException">ログインに失敗した時</exception>
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));
if (string.IsNullOrWhiteSpace(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);
Expand Down
35 changes: 33 additions & 2 deletions TVTComment/Model/NiconicoUtils/NiconicoLoginSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
/// <summary>
/// 送信するべき認証情報を含んだクッキー
Expand All @@ -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;
}

/// <summary>
Expand All @@ -74,9 +81,20 @@ public NiconicoLoginSession(string mail, string password)
/// <exception cref="NetworkNiconicoLoginSessionException"></exception>
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();
Expand All @@ -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;
}

Expand All @@ -128,6 +156,9 @@ public async Task Logout()
throw new NetworkNiconicoLoginSessionException(e);
}
this.cookie = null;
this.nicosid = null;
this.session = null;
this.secure = null;
}
}
}
8 changes: 7 additions & 1 deletion TVTComment/ViewModels/SettingsWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class SettingsWindowViewModel : BindableBase
public ObservableValue<string> NiconicoLoginStatus { get; } = new ObservableValue<string>();
public ObservableValue<string> NiconicoUserId { get; } = new ObservableValue<string>();
public ObservableValue<string> NiconicoPassword { get; } = new ObservableValue<string>();
public ObservableValue<string> NiconicoSid { get; } = new ObservableValue<string>();
public ObservableValue<string> NiconicoSession { get; } = new ObservableValue<string>();
public ObservableValue<string> NiconicoSecure { get; } = new ObservableValue<string>();
public ObservableValue<string> NichanResCollectInterval { get; } = new ObservableValue<string>();
public ObservableValue<string> NichanThreadSearchInterval { get; } = new ObservableValue<string>();
public ObservableValue<string> NichanApiHmKey { get; } = new ObservableValue<string>();
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down