CakePHPで ?guid=ONを常にURLに入れる

ドコモがガンとしてCookieに対応しないため、携帯でセッションを引き継ぐには、パラメータの中にセッションIDを(できれば自動で)入れる仕組みが必須なわけです。
しかし、セッションID付きのURL。
これは外部に漏れると不正アクセスされる危険なもの。

「どうせ全てのURLになんらかのパラメータ入れる必要あるなら、?guid=ONをいれればいいじゃん。
 そして携帯IDでセッションひきつげばいいじゃん」

携帯で ?guid=ONがURLに入ってて、セッションIDらしきものがないサイトは、上の設計でセッションを引き継いでるものと思われます(多分)

が。
フレームワークだと、自動でリンクやリダイレクトが発行されるので、「全てのURLに付加」が早々カンタンには行きません・・・

そんなこんなの試行錯誤。
 っていうか、ドコモが「?guid=ONというパラメータが必須」なんて言わなければこんな苦労ないんですが (T-T)
 そのくせ、「SSLじゃダメー」とか言い出すんだから、ワケわかりません。
 グチってもせん無き事ですが・・・

リンクに自動で付与

これはカンタン。
app_controller.phpで、beforeFilter()に以下の通り設定。
cake/libs/controller/app_controller.php

(前略)
class AppController extends Controller {
(中略)
    function beforeFilter() {
(中略)
            // URLパラメータに必ずguid=ONを付与
            output_add_rewrite_var('guid','ON');

参考 http://www.happytrap.jp/blogs/2009/03/24/797/

ただし・・・
上記記事では、これだけでactionにも guid=ONが入ったそうですが、実際にはそうなりませんでした (?_?)

POSTのguid=ONではダメですので、別途対策が要ります。
  おドコモ様の仕様は厳しい orz

フォームヘルパー(POST)に自動で付与

フォームヘルパーの調査。。

cake/libs/view/helpers/form.php

class FormHelper extends AppHelper {
(中略)
	function create($model = null, $options = array()) {
(中略)
			$options['action'] = array_merge($actionDefaults, (array)$options['url']);
(中略)
		$htmlAttributes['action'] = $this->url($options['action']);
		unset($options['type'], $options['action']);

$htmlAttributes['action']が、action="***"の中身のようです。

では、$this->url()の処理は?
cake/libs/router.php

class Router extends Object {
(中略)
	function url($url = null, $full = false) {
(中略)
			if (isset($url['?'])) {
				$q = $url['?'];
				unset($url['?']);
			}
(中略)
		return $output . $extension . $_this->queryString($q, array(), $escape) . $frag;

・・・読解。


つまり、

1. $this->url($url) で、$url['?'] = 'guid=ON';
2. すなわち、$form->create($model, $options)で、$options['url']['?'] = 'guid=ON';

という推測の元に、テンプレートを書き換え。

app/views/members/add.ctp

<?php echo $form->create('Member');?>
↓
<?php echo $form->create('Member', array('url' => array('?' => 'guid=ON')));?>

これで成功しました!

・・・POSTのguid=ONも残っちゃってますが。。。
 実害ないし、とりあえずこれで。

ただ、テンプレートごとに、追記必要です。
拡張フォームヘルパー作ろうにしようかな・・・


(追記)拡張ヘルパー作りました
app/views/helpers に、下記の内容のmobileform.phpを作成。members_controller.phpとadd.ctpの設定をちょっと変えました。

mobileform.php

<?php

class MobileformHelper extends FormHelper {
    function create($model = null, $options = array()) {
        if (!isset($options['url']) || is_array($options['url'])) {
            if (!isset($options['url']['?']) || !$options['url']['?']) {
                $options['url']['?'] = 'guid=ON';
            } else {
                $options['url']['?'] .= '&guid=ON';
            }
        } elseif (is_string($options['url'])) {
                $options['url'] .= '&guid=ON';
        }
    return parent::create($model, $options);
    }

}

members_controller.php

    var $helpers = array('Html', 'Form', 'Mobileform');

add.ctp

<?php echo $mobileform->create('Member');?>

参考http://www.exgear.jp/blog/2009/06/cakephp-form%E3%83%98%E3%83%AB%E3%83%91%E3%81%AE%E6%8B%A1%E5%BC%B5-%E3%81%9D%E3%81%AE%EF%BC%91-%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%97%A5%E4%BB%98%E9%81%B8%E6%8A%9E%E3%83%97%E3%83%AB%E3%83%80%E3%82%A6/

リダイレクトに自動で付与

$this->redirect($url)の書き換え。
http://cakephp.jp/modules/newbb/viewtopic.php?post_id=1398&topic_id=751&forum=3
↑のhide99さんの書込みを参考にしましたが、$urlには、文字列指定と配列指定の2種類があり、
この方法は配列に対応してませんでした。

そこで一ひねり。。

    // 携帯の場合、redirectにguid=ONを付与
    function redirect($url, $status = null)
    {
        if (!$this->agent->isNonMobile()){
            // redirectの配列指定に対応
            if (is_array($url)) {
                $url['base'] = false;
                $url = Router::url($url);
            }
            $url = $url."?guid=ON";
        }

        parent::redirect($url, $status);
    }

これで成功!