何度やっても同じ

ただの日記

TwitterのOAuth認証プロセスがリダイレクトループしたとき

原因はいくつかパターンがあるようですが、サーバサイドがJavaの場合、誤ったURLリライティングによってリダイレクトループに陥ることがあります。というか、陥りました。

一見問題なさげな次のコードですが(slim3使ってます)。。。

StringBuffer callbackURL = request.getRequestURL();
int index = callbackURL.lastIndexOf("/");
callbackURL.replace(index, callbackURL.length(), "").append("/callback");

Twitter twitter = TwitterService.getTwitterInstance();
RequestToken requestToken = twitter.getOAuthRequestToken(callbackURL.toString());
sessionScope("requestToken", requestToken);

return redirect(requestToken.getAuthenticationURL());

slim3はこの後、redirectメソッドに渡したパスに対してresponse.encodeRedirectURL()を呼び出しておりまして、このコードだとrequestToken.getAuthenticationURL() の戻り値であるtwitter apiのURLをリライティングしてjsessionidをくっつけてしまう場合があるのです。次のような感じに。

http://api.twitter.com/oauth/authenticate;jsessionid=xxxxxx?oauth_token=xxxxxx

URLがこうなってしまうと、あとはtwitter内部の問題なので詳細は知りませんが、リダイレクトループに陥ってしまいます。

これを回避するには、こう。

StringBuffer callbackURL = request.getRequestURL();
int index = callbackURL.lastIndexOf("/");
callbackURL.replace(index, callbackURL.length(), "").append("/callback");

// こっちをURLリライティング
String rewritedURL = response.encodeRedirectURL(callbackURL.toString());

Twitter twitter = TwitterService.getTwitterInstance();
RequestToken requestToken = twitter.getOAuthRequestToken(rewritedURL);
sessionScope("requestToken", requestToken);

// 勝手にURLリライティングしないように自分でリダイレクトロジック書く
response.sendRedirect(requestToken.getAuthenticationURL());
return null;