C#
api
Unity
ニコニコ動画

UnityでニコニコAPI使おうとしたら詰まった件

ニコニコのAPI経由で動画を取得しようとすると以下のような手順が必要です。

  • ログインAPIにIDとパスワードをPOSTしてCookie user_sessionを取得
  • user_sessionを含むCookieを持たせ動画URLにGETリクエストしCookie nicohistoryを取得
  • getflv APIにuser_sessionとnicohistoryを含むCookieを持たせGETリクエストして動画URLを取得
  • 動画URLにuser_sessionとnicohistoryを含むCookieを持たせGETリクエストして動画を取得

非常にめんどくさいですが全部WebRequestなのでURLとCookie用のHashtableさえ用意すれば簡単に行く

はずなんですが。

ログインAPIにPOSTしてもSet-Cookieヘッダにuser_sessionが含まれないのです。

というわけで数時間思考した結果に見つけた結論を以下にはっつけておきます。

NiconicoAPI.cs
using UnityEngine.Networking;

public class NiconicoAPI {
    public const string NICONICO_LOGIN_URL = "https://secure.nicovideo.jp/secure/login?site=niconico";
    public string userSession = null;

    public IEnumerator Login() {    
        string id = "your@mail.address";
        string pass = "yourpassword";

        WWW form = new WWWForm();
        form.AddField("mail_tel", id);
        form.AddField("password", pass);

        UnityWebRequest www = UnityWebRequest.Post(NICONICO_LOGIN_URL, form);

        //これがめっちゃ重要
        www.redirectLimit = 0;

        yield return www.SendWebRequest();

        Dictionary<string, string> headers = www.GetResponseHeaders();

        string setCookieHeader = null;
        try {
            setCookieHeader = www.GetResponseHeader()["set-cookie"];
        } catch(KeyNotFoundException keyNotFoundException) {
            //post情報が間違っててSet-Cookieすら含まれない状態
            Debug.Log(keyNotFoundException.Message);
        }

        //Set-Cookieヘッダに含まれるuser_sessionは3つあって、そのうち必要なものはuser_sessionから始まる
        //他は"deleted"とsecureなんたらとかいうの。いらない。(知らんけど)
        foreach(string cookie in setCookieHeader.Split(new string[] {"user_session="}, StringSplitOptions.None)) {
            if(cookie.StartsWith("user_session")) {
                this.userSession = cookie.Split(';')[0];
            }
        }        
        www.Dispose();
    }
}

とこんな感じになります。

ニコニコのログインAPIって、ログイン情報渡した後に公式サイトかユーザーページにリダイレクトしてくるっぽいのです。

そしてリダイレクト時に新たなSet-Cookieヘッダがセットされる?ためログイン時にセットされたSet-Cookieヘッダが消える?のです。

なので、UnityWebRequestのインスタンスのredirectLimitを0にしてやるとRedirectを許さないリクエストになりLoginサーバーがセットしたSet-Cookieヘッダがそのまま受け取れます。

ちなみに、残りのGETリクエストに関してはredirectLimitは必要ないです。