SiNBLOG

140文字に入らないことを、極稀に書くBlog

Slim3でtwitter4jを使ってTwitterアカウントにサインインする

twitter4j公式ページのサンプルを、Slim3で作ってみました。
GitHub - yusuke/sign-in-with-twitter

ちょっと、僕の力不足により全て同じにはできませんでした。
それでも、Twitterアカウントにサインインする部分は同一のはずです。

まずは、SigninServletを元にしたSigninController


public class SigninController extends Controller {

@Override
public Navigation run() throws Exception {
final String consumerKey = "7lHcFOarYnrCtX7etyj4gA";
final String consumerSecret = "CW2zwOkYzZSjMF3zyvFj94YnqN6slanH8cX0IHKM";

Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(consumerKey, consumerSecret);
sessionScope("twitter", twitter);
try {
StringBuffer callbackURL = request.getRequestURL();
int index = callbackURL.lastIndexOf("/");
callbackURL.replace(index, callbackURL.length(), "").append("/callback");

RequestToken requestToken = twitter.getOAuthRequestToken(callbackURL.toString());
sessionScope("requestToken", requestToken);
response.sendRedirect(requestToken.getAuthenticationURL());
return null;
} catch (TwitterException e) {
throw new ServletException(e);
}
}
}

consumerKeyとconsumerSecretは、自分のアプリのものに置き換えて下さい。
また、twitter.getOAuthRequestToken()にCallbackURLを指定しなかった場合
リダイレクトが複数回発生し、ブラウザに怒られることがあります。
僕はこれに気付かず、TwitterAPIの方でCallbackURL指定してるから不要なのかと思い
長い間、ブラウザに怒られ続けていました・・・。
指定しなくても、CallbackURLに戻っては来るので(TwitterAPIで指定してるから?)
ハマるとしんどいポイントかも。

2012/02/09 追記
CallbackURLを指定してもリダイレクトループが発生してしまいました・・・。
その後、あれこれ調べていたのですが、Controller.redirect()を使わなければ大丈夫・・・?
中で、HttpServletResponse#encodeRedirectURL()を呼んでいるので、jsessionidが付加されてしまっているようです。
そのため、Controller.redirect()は使わずに、response.sendRedirect()を利用した方が良さそうですね。


次は、CallbackServletを元にしたCallbackController


public class CallbackController extends Controller {

@Override
public Navigation run() throws Exception {
Twitter twitter = (Twitter)sessionScope("twitter");
RequestToken requestToken = (RequestToken)sessionScope("requestToken");
String verifier = requestScope("oauth_verifier");
try {
twitter.getOAuthAccessToken(requestToken, verifier);
removeSessionScope("requestToken");
} catch (TwitterException e) {
throw new ServletException(e);
}
return redirect(basePath);
}
}

Twitterから渡されたoauth_verifierパラメータを使って、AccessTokenを取得しています。
今回はTwitterオブジェクトをSessionに格納していますが、一度認証してしまえば
consumer key/secret と AccessToken のみでユーザアカウントにアクセスできます。


これでTwitterアカウントにサインインは完了です。
twitter4j公式ページのサンプルには、logoutとpostもありましたので、作ってみました。


PostServletを元にしたPostController


public class PostController extends Controller {

@Override
public Navigation run() throws Exception {
String text = requestScope("text");
Twitter twitter = (Twitter)sessionScope("twitter");
try {
twitter.updateStatus(text);
} catch (TwitterException e) {
throw new ServletException(e);
}
return redirect(basePath);
}
}

Sessionから取得したTwitterオブジェクトを使って、ツイートしています。


LogoutServletを元にしたLogoutController


public class LogoutController extends Controller {

@Override
public Navigation run() throws Exception {
request.getSession().invalidate();
return redirect(basePath);
}
}

Sessionを削除しているだけで、特にtwitter4jの機能は使っていません。


実際のソースはこちら。
Java
Google Code Archive - Long-term storage for Google Code Project Hosting.
jsp
Google Code Archive - Long-term storage for Google Code Project Hosting.