note-12の動作中におけるブラウザ側のCookieを確認しましたが,3の時点で自動ログイン用のCookieが削除された状態であることを確認しました.ここでソースを見てみると,自動ログイン用のCookieが変更される部分はlib/user/opSecurityUser.class.phpのsetRememberLoginCookie()です.該当箇所は以下のようになります.
lib/user/opSecurityUser.class.php
154 /**
155 * set remember login cookie
156 */
157 protected function setRememberLoginCookie($isDeleteCookie = false)
158 {
159 $key = md5(sfContext::getInstance()->getRequest()->getHost());
160 $path = sfContext::getInstance()->getRequest()->getRelativeUrlRoot();
161 if (!$path)
162 {
163 $path = '/';
164 }
165
166 if ($isDeleteCookie)
167 {
168 if (!sfContext::getInstance()->getRequest()->getCookie($key))
169 {
170 return;
171 }
172
173 if ($this->getMemberId())
174 {
175 $this->getMember()->setConfig('remember_key', '');
176 }
177
178 $value = null;
179 $expire = time() - 3600;
180 }
181 else
182 {
183 $rememberKey = opToolkit::getRandom();
184 if (!$this->getMemberId())
185 {
186 throw new LogicException('No login');
187 }
188 $this->getMember()->setConfig('remember_key', $rememberKey);
189
190 $value = base64_encode(serialize(array($this->getMemberId(), $rememberKey)));
191 $expire = time() + sfConfig::get('op_remember_login_limit', 60*60*24*30);
192 }
193
194 sfContext::getInstance()->getResponse()->setCookie($key, $value, $expire, $path, '', false, true);
195 }
196
このソースより,setRememberLoginCookie()の引数にtrueを渡す処理を行うとCookieが削除される動作が行われると思います.
そしてsetRememberLoginCooike()の引数にtrueを渡すのは同ファイル内logout()だけであることを確認しました.
このlogout()がどこのタイミングで呼び出されるかを確認するために以下の実験を行いました.
実験内容¶
ログ出力部分変更を加えてdev環境によってログを収集し,logout()が呼び出されるタイミングを確認する.
実験手順¶
- SNSに自動ログインを有効にしてログイン
- ブラウザ終了
- ログ開始
- 同ブラウザを立ち上げてSNSにアクセス
- ホームを表示
ログ収集のための変更内容¶
diff --git a/lib/user/opSecurityUser.class.php b/lib/user/opSecurityUser.class.php
index 7d66a46..490b26f 100644
--- a/lib/user/opSecurityUser.class.php
+++ b/lib/user/opSecurityUser.class.php
@@ -289,6 +289,7 @@ class opSecurityUser extends opAdaptableUser
{
$authMode = $this->getCurrentAuthMode();
+ $this->dispatcher->notify(new sfEvent($this, 'application.log', array("opSecurityUser logout()")));
$this->setRememberLoginCookie(true);
$this->setAuthenticated(false);
@@ -329,6 +330,7 @@ class opSecurityUser extends opAdaptableUser
if ($member instanceof opAnonymousMember || $member->getIsLoginRejected())
{
+ $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf("%s || %s", get_class($member), $member->getIsLoginRejected()))));
$this->logout();
$isSNSMember = false;
}
実験結果¶
結果は以下のとおり.ルーティングやレンダリングに関するログは省略.
Sep 28 21:14:22 symfony [info] {sfPatternRouting} Match route "homepage" (/) for / with parameters array ( 'module' => 'member', 'action' => 'home',)
9月 28 21:14:22 symfony [info] {myUser} opAnonymousMember ||
9月 28 21:14:22 symfony [info] {myUser} opSecurityUser logout()
9月 28 21:14:22 symfony [info] {myUser} User is not authenticated
9月 28 21:14:22 symfony [info] {myUser} User is not authenticated
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "sfRenderingFilter"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "opCacheControlFilter"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "opCheckEnabledApplicationFilter"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "opAppendXRDSHeaderFilter"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "opRememberLoginFilter"
9月 28 21:14:22 symfony [info] {myUser} User is authenticated
9月 28 21:14:22 symfony [info] {myUser} Add credential(s) "SNSMember"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "sfBasicSecurityFilter"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "opEmojiFilter"
9月 28 21:14:22 symfony [info] {sfFilterChain} Executing filter "opExecutionFilter"
9月 28 21:14:22 symfony [info] {memberActions} Call "memberActions->executeHome()"
9月 28 21:14:22 symfony [info] {memberActions} Change layout to "layoutA"
9月 28 21:14:22 symfony [info] {opView} Set customize "cautionAboutFriendPre" (friend/cautionAboutFriendPre)
9月 28 21:14:22 symfony [info] {opView} Set customize "cautionAboutCommunityMemberPre" (community/cautionAboutCommunityMemberPre)
…
9月 28 21:14:23 symfony [info] {opWebResponse} Send status "HTTP/1.1 200 OK"
9月 28 21:14:23 symfony [info] {opWebResponse} Send header "Content-Type: text/html; charset=utf-8"
9月 28 21:14:23 symfony [info] {opWebResponse} Send header "Expires: Fri, 22 Apr 1988 17:00:00 GMT"
9月 28 21:14:23 symfony [info] {opWebResponse} Send header "Lastmodified: Wed, 28 Sep 2011 12:14:23 GMT"
9月 28 21:14:23 symfony [info] {opWebResponse} Send header "Cache-Control: no-store, no-cache, private, max-age=0, must-revalidate, post-check=0, pre-check=0"
9月 28 21:14:23 symfony [info] {opWebResponse} Send header "Pragma: no-cache"
9月 28 21:14:23 symfony [info] {opWebResponse} Send cookie "2dc1b1d9f6936933a8af7f0f643c3ab9": ""
9月 28 21:14:24 symfony [info] {opWebResponse} Send content (875197 o)
…
上記よりわかること¶
ブラウザを立ち上げ直した後最初にSNSにアクセスした場合,opAnonymousMemberでアクセスした状態となり,logout()が実行されて自動ログイン用のセッションが初期化される.この時,opSecurityUser.class.phpの175行目でセッションを初期化しようとするがopAnonymousMemberのためDBのテーブルの方は初期化されない.しかし194行目の処理によってCookieを削除してしまう.その後opRememberLoginFilterによってブラウザから送られてきたCookieを用いてログインが成功する.次にホームが表示されたときには先程の処理によってCookieが削除されてしまうため次のログインが行われない状態となっている.
ブラウザ内のCookieが削除される.