bestlong 怕失憶論壇's Archiver

bestlong 發表於 2013-4-24 23:09

Yii 的奇怪特性,登入成功會更換 session id

網購系統都會有將商品加入購物車的功能
不過會員尚未登入就無法用會員編號來連結管理
若是資料儲存在資料庫多數都會利用 session id 來當關聯值

這在我使用 Yii 開發此功能後進行會員登入卻發現購物車空無一物
但是檢查資料庫中還看得到列表

取得 session id 的方式:[code]
//用 PHP 函數
echo session_id();
//用 Yii 的方法
echo Yii::app()->session->sessionID;
[/code]研究程式碼一直追到 yii framework 的部分才了解問題的根源
是在 CWebUser::login() 內有呼叫 changeIdentity()
然後執行了 Yii::app()->getSession()->regenerateID(true);
這裡的參數名稱是 deleteOldSession
因為直接設定了 true 所以後續就強制更換 session_id 了

基於以上特性描述,所以只要登入成功那就等於是換了車鑰
原本的用 session id 關聯的購物車清單就無主之車了

會有這樣的設計,或許是提升安全性的考量,決不能直接斷定是錯的
因為是經過設計的框架,我認為應該是留有伏筆
還需要再深入研究

[color=Blue]PS:以上是使用 yii-1.1.13.e9e4a0 版本的環境[/color]

bestlong 發表於 2013-4-27 00:17

針對登入成功後 yii 框架會把 Session Id 重新設定的特性
說說我的想法
首先不能有先入為主的觀念,認為這樣特性是錯誤的
會認定是錯誤的朋友應該就是以往都習慣直接應用 session_id 的開發者

我認為 yii 是經過設計的框架,只有入鄉隨俗去適應與理解

雖然 session id 會被更換,不管是基於什麼原因
但至少更換前設定在 $_SESSION 內的資料在更換後都還是保留下來
所以可以換個方式處理,例如:[code]
class CartController extends Controller
{
  public function actionAjaxAddToCart()
  {
    if(!isset(Yii::app()->session['cart_key']))
    {
      Yii::app()->session['cart_key'] = session_id(); //將目前 Session ID 保存起來
    }
    $cart_key = Yii::app()->session['cart_key'];
    $product_id = $_GET['product_id'];
    $cart = Cart::model()->findByAttributes(array(
      'cart_key'=>$cart_key,
      'product_id'=>$product_id,
    ));
    if($cart===NULL)
    {
      //新增
    }
    else
    {
      //增加數量
    }
    ...後略...
  }
}
[/code]這樣就可以用 $cart_key 來解決問題了,而不是也不需要自己繼承 Class 或改寫 framework。

bestlong 發表於 2013-5-5 23:23

在 Yii 官方討論區
[url]http://www.yiiframework.com/forum/index.php/topic/42664-user-%E7%99%BB%E5%85%A5%E6%88%90%E5%8A%9F%E5%BE%8C%E6%9C%83%E6%9B%B4%E6%8F%9B-session-id-%E5%8F%AF%E4%BB%A5%E8%A8%AD%E5%AE%9A%E6%88%90%E4%B8%8D%E6%8F%9B%E5%97%8E/[/url]
來自 痴苶呆傻 的提議
是否可以考虑使用
Yii::app()->user->setState(... );
Yii::app()->user->getState(... );
來代替直接 session 操作
頁: [1]

Powered by Discuz! X1.5 Archiver   © 2001-2010 Comsenz Inc.