Drupal 6のセッション管理(3)

検討の結果、携帯電話端末のセッション管理をセッションIDをURLに埋め込むという方向で行こうと決定しました。ただ、デフォルトでの設定で動作しているDrupalのURLを見ると、PHPSESSION等というものが見あたらないと思います。Cookieでセッション管理を行うのがデフォルトだからです。まずは、セッションIDをURLに入れるところから始めましょう。

Drupal のテーマを作ったことあるなら、すぐにリンクタグ(<a>)を作る場合、主に使う関数 l() を修正する必要があると考えると思います。しかし、前回のブログでも見たとおり、セッション・ハンドラーは独自に作り直していますが、セッション管理機構はPHPのものを使っていますので、これにそった形で修正を進めるのが良いと思います。

まず、URLにセッションIDが付加されるようにしましょう。このセッションIDを「透過的なセッションID」といいます。PHPの方で自動的にリンクタグ等にもセッションIDが入らなくては使い物になりませんが、この辺もPHPが勝手にやってくれます。このオプションを設定するには、settings.php のsession.use_trans_sid の設定を'1'にしてやる必要があります。今回はCookieをまったく使わないでやってみるというのが目的ですので、settings.phpを以下のように設定しました。

ini_set('session.use_cookies', 0);
ini_set('session.use_only_cookies', 0);
ini_set('session.use_trans_sid', 1);

簡単に設定できました。しかし、これだけではリンクタグとかに透過的なセッションIDを付加したURLが生成されませんので、その近くにあるリライト規則を追加します。

settings.php:ini_set('url_rewriter.tags', 'a=href,area=href,frame=src,input=src,fieldset=');

これでセッションIDがURLに付加されるようになったと思います。

しかし、まだログインができません。何故でしょう?それの答えはここにありました。要約するとdrupal_goto()が、この透過セッションIDに対応しなくなったからなのです。セッション・フィクセーションの事を考えると当然の対応です。

仕方ないので drupal_goto()関数を書き換えて対応するしかなさそうです。drupal_goto()は、includes/common.incにあります。該当する行を見ると確かにURLに新しくログイン後に発行されたセッションIDを付与するところがありません。

function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) {

if (isset($_REQUEST['destination'])) {
extract(parse_url(urldecode($_REQUEST['destination'])));
}
else if (isset($_REQUEST['edit']['destination'])) {
extract(parse_url(urldecode($_REQUEST['edit']['destination'])));
}

$url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE));
// Remove newlines from the URL to avoid header injection attacks.
$url = str_replace(array("\n", "\r"), '', $url);
 // この辺に入れたらよいような・・・
// Allow modules to react to the end of the page request before redirecting.
// We do not want this while running update.php.
if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
module_invoke_all('exit', $url);
}

// Even though session_write_close() is registered as a shutdown function, we
// need all session data written to the database before redirecting.
session_write_close();

header('Location: '. $url, TRUE, $http_response_code);

// The "Location" header sends a redirect status code to the HTTP daemon. In
// some cases this can be wrong, so we make sure none of the code below the
// drupal_goto() call gets executed upon redirection.
exit();
}

セッションIDを付加していないと言うことだけなら、単純にセッションIDを付加して、リダイレクトするだけで可能なのではということになります。その通りなんですが、そのパッチ(注意:古いのでそのままは使えません)はあります。何か、スマートじゃないですね。でも、 セッションIDを$urlに追加する文を上の赤字の箇所に加えると、確かにセッションIDを引継ぎながら移動できるので、ログイン問題は解決されます。

if (ini_get('session.use_trans_sid') && session_id() && !strstr($url, session_id()) && !$_COOKIE[session_name()]) {
$sid = session_name() . '=' . session_id();

if (strstr($url, '?') && !strstr($url, $sid)) {
$url = $url .'&'. $sid;
}
else {
$url = $url .'?'. $sid;
}
}

注意:Drupal のセッション管理がどの程度セッション・フィクセーションに強いか確認してから実際に実装してくださいね。まだ、そこまでコードを追いきれていないので。

ソーシャル・リンク

コメント

新しいコメントの投稿

このフィールドの内容は非公開にされ、公表されることはありません。

書式オプションに関するより詳しい情報...

CAPTCHA
このフォームは投稿者が人間であるかどうか確認し、自動的なスパム投稿を妨げるために実施しています。
Image CAPTCHA
画像に表示されている文字(空白以外)を入力してください。

 

Drupal Association Organisation Member

お奨めサイトフィード

Drupal ブログ

Walnutsスタッフブログ

コンテンツ配信

ウィジェット