それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

radiko の js プレイヤーのリクエストを追いかける

radikoがJSになってた

swftoolsいらない可能性があるので追いかける。

auth1 /auth2

従来通り、auth1 / auth2 に投げるのは変化なし。

auth1 で auth_token を貰ってきて auth2 で auth_token で署名をもらうイメージ

auth1 にリクエストを投げて、次の値を取る。

< X-Radiko-AuthToken: m_9ub1okKzi1vctuMS0NNg
< X-Radiko-KeyLength: 16
< X-Radiko-KeyOffset: 6

auth_token がセッションキー

だいたいこんな感じだった。

/// auth 1 の値を持っておいて
var auth_token
var auth_key = "bcd151073c03b352e1ef2fd66c32209da9ca0afa" // 現状は固定
var key_length
var key_offset

x = str2Buffer( auth_key )
y  = new Uint8Array(b, key_offset,key_length )

for (var r = y, a = "", i = 0; i < r.length; i++){ a += String.fromCharCode(r[i]); }

partial_key = btoa(a)

///auth2へ
str2Buffer = (e) =>  {
      return new Uint8Array([].map.call(e, function(e) {
        return e.charCodeAt(0)
      })).buffer
}

メッチャバイト列に戻してるけどそれいるのか

auth2 のリクエス

fetch("https://" + location.host + "/v2/api/auth1", {
        headers: {
          "X-Radiko-App": this._appId, // pc_html5固定
          "X-Radiko-App-Version": "0.0.1",
          "X-Radiko-User": "dummy_user",
          "X-Radiko-Device": this._device  //'pc' 固定
        },
        method: "get",
        credentials: "include"
      }).

auth1 は curl で直叩き出来る

curl -v \
-H 'X-Radiko-App: pc_html5' \
-H 'X-Radiko-App-Version: 0.0.1' \
-H  'X-Radiko-User: dummy_user' \
-H  'X-Radiko-Device: pc' \
    https://radiko.jp/v2/api/auth1

*   Trying 203.211.199.120...
* TCP_NODELAY set
* Connected to radiko.jp (203.211.199.120) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: radiko.jp
* Server certificate: RapidSSL SHA256 CA
* Server certificate: GeoTrust Global CA
> GET /v2/api/auth1 HTTP/1.1
> Host: radiko.jp
> User-Agent: curl/7.56.1
> Accept: */*
> X-Radiko-App: pc_html5
> X-Radiko-App-Version: 0.0.1
> X-Radiko-User: dummy_user
> X-Radiko-Device: pc
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Wed, 08 Nov 2017 18:06:18 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Radiko-AppType: pc
< X-Radiko-AppType2: pc
< X-Radiko-AuthToken: iTzjvyV51b5KGS6i4yaLsA
< X-Radiko-AuthWait: 0
< X-Radiko-Delay: 15
< X-Radiko-KeyLength: 16
< X-Radiko-KeyOffset: 0
< Access-Control-Expose-Headers: X-Radiko-AuthToken, X-Radiko-Partialkey, X-Radiko-AppType, X-Radiko-AuthWait, X-Radiko-Delay, X-Radiko-KeyLength, X-Radiko-KeyOffset
< Access-Control-Allow-Credentials: true

auth2

auth2 のリクエス

 fetch("https://" + location.host + "/v2/api/auth2", {
        headers: {
          "X-Radiko-AuthToken": this._token,
          "X-Radiko-Partialkey": this._partialKey,
          "X-Radiko-User": "dummy_user",
          "X-Radiko-Device": this._device // 'pc' 固定
        },
        method: "get",
        credentials: "include"

なんでわざわざJSにはUInt8ArrayやArrayBufferのバイナリ処理が入ってるのかよくわからない。元が文字列なら、str.split('')で良いんだし。わざわざバイナリ処理にしてるってことは、将来的に auth_key を画像とかバイナリとか暗号化データにするつもりなんだろうかね

auth_key の文字列をレスポンスのoffset と length 分だけ切り取ってbase64するだけなので以前に比べると楽になってるんじゃなかろうか。たぶんcurlbashだけで簡単にかける。眠いのでまた明日。