Shaw's Home Page(本館)

はてなダイアリーから引っ越しました。

Facebookのアクセストークンの有効期限について調べてみた

2012年8月4日補足
今もこの記事にたどり着く方が結構多いようですが、内容はすでにちょっと古いです。
おそらく下記URLの内容のほうが、大いに参考になるかと思います。
offline_accessパーミッション削除に対応する

久々にFacebookAPIネタです。お題は、とあるFacebookページの最新Feedをcron使って定期的に取得したい、というケースでどうすればいいのか、です。ちょっとはまったのでメモを残しておく。

まず最初に考えたのは、有効期限のない固定化されたアクセストークンを取得して、そのトークンを使ってgraph APIにリクエストを投げるという方法。普通にアクセストークンを取得すると1時間〜2時間という有効期限がセットされてしまうけど、offline_access権限をつけて取得したアクセストークンは固定化されるはずなので、あとはGraph APIエクスプローラにて適当なアカウントで固定化されたアクセストークンを取得して、それをずっと利用しつづければいいのでは?と思ったわけですね。

ところがです。Graph APIエクスプローラでoffline_accessを指定してアクセストークンを取得しようとしても、なぜかoffline_access権限が付与されない。はて…おかしい、と思ってみると、こんな話題に突き当たった。

開発者ロードマップ(2012-03-06)

2012年5月1日にoffline_accessが完全に廃止される

…な、なんだってー!

いや、私もですね、Offline_access権限って危険な代物だよなぁ…とは思っていたんです。だから、これまでも仕事でFacebookアプリを作る際、一度もOffline_accessを求めたことはなかったんだけど、利用方法としてバッチ処理では必須なんじゃね?と思っていたわけですよ。なのにこれが完全に廃止されるという。おそらくGraph APIエクスプローラでOffline_accessが付与されなかったのも、この仕様変更が理由なんでしょう。

さて、そうなると方針を変える必要が出てくるわけで。単純に考えると、有効期限のないアクセストークンが取得できないということは、バッチ処理を実行するたびに新しいアクセストークンを都度取得して、それをAPIのリクエスト時に利用しかないのかなぁ…という結論にしかたどり着かないわけだけど。バッチ処理ってユーザーのログインって概念がない(よね?)のに、どうやってOauth経由のアクセストークンを取得するんだ?

全然やり方が思いつかないので、久々に人力検索に質問を投げてみましたよ*1

ただ、数時間経ってもレスがつかない。気になってたまらないのでさらに自分で調査を進めてみた。すると今度はこんなページにたどり着いた。

Facebook アプリの認証トークンが2時間で切れる問題

お、これはだいぶ核心にたどり着いたのでは?と思いよく読んでみる。ここに書いてある通りだとすると、自分が作成したアクセストークンも有効期限が60日間になっているはずなんだけど、デバッガーで確認してみる限りやっぱり2時間しかもたない。なぜだ。

結局このページを読んでも解決策は見つからなかったのだけども、それとは別の収穫物があった。アクセストークンっていくつか種類があるの?ということ。Application Tokenってなんですか?それおいしいの??

そしてついにたどり着いたのはこのページ。本家Facebookのドキュメント。
Authentication

In addition to obtaining User access tokens, it's possible to obtain App access tokens and Page access tokens.

だと。さらにここで、Application Tokenの取得方法もかいてある*2。このトークンには、通常のアクセストークン(user access tokenという名称で区別されてる)と違って有効期限という概念がないらしい。そこでようやく思い当たったのが、facebookが提供してるPHPSDK。以前デバッグの必要があって中身のソースを読んでた際に、getAccessToken()関数が二段階に渡ってメンバ変数にアクセストークンをセットする処理をやってたんだけど、これ、最初にApp access tokensを取得して、さらにUser Access Tokenも取得出来る場合はそちらを優先する、ということをやってるのね。

User Access Tokenは、ログインしてるユーザー毎に発行されるトークン情報なので、Facebookのキモとなるgraph APIはこのトークンじゃないと取得できないデータが大部分だと思うんだけど、その分管理方法も厳密で、エンドポイントごとに必要な権限だったり有効期限がかなりきめ細やかに設定できたりする。逆にApp access tokenは、アプリに対するトークン情報なので出来ることが限られているけど、バッチ処理で必要になるだろう最低限の権限は用意されている。つまり、バッチ処理のように、有効期限が決まってると処理に困るケースはこっちのトークンを使いなさいよ、ということなのではないだろうか?というのが、ここまで来て自分なりに得た結論。Facebook側の言い分がそうなのかはわからないけど…。

もちろん、元々お題としていたFacebookページの最新Feedをバッチ処理で取得ということもできましたよ!超ザルだけどサンプルはこんな感じ。

<?php
// あらかじめ取得しておいたApp access tokens
$access_token = 'XXXXX';

// 取得したいFeedのあるFacebookページID
$fbpage_id = 'YYYYY';

$request_url = "https://graph.facebook.com/{$fbpage_id}/feed?access_token={$access_token}";
$json = @file_get_contents($request_url);
$feed = json_decode($json);

// 以下、取得できたFeedデータから、使いたい分をごにょごにょする

最後にちょっと思ったこと。アプリの許可を求められるFacebookアプリで、しょっしゅうOffline_access権限を求められることがあって、個人的にはそういうアプリは大抵信用してなかったんだけど、5月1日以降Offline_accessが廃止されると影響を受けるアプリも多いってことなんじゃないのかなぁ。私も今日までこの仕様変更のことを知らなかったけど、世間的に大丈夫なのだろうか。また直前になってどたばたする人が多数でそうな予感が…。

*1:ただし回答がつく前に自己解決したのでキャンセル済み

*2:英語を読むのが嫌であればこのページが役立つかもね。