当我触摸CWebUser时,Yii总是开始一个会话

时间:2015-04-21 15:41:21

标签: php session yii

我正在开发一个RESTful API服务器,它在某些API方法上需要一个有效的会话,以带有会话ID的cookie的形式表示。

我正在使用Yii v1.1.15和库存PHP会话处理程序(可能是'文件')。

事情就是每次调用CWebUser时都会创建一个会话而我不希望这样。只有在我明确创建会话时,才会存在会话,这意味着在登录时(或者自动登录用户的注册)。例如,如果在某个API方法中,我使用包含以下内容的构造检查用户是否是来宾:

Yii::app()->user->isGuest

它自动创建会话,因为此代码在CWebUser.init()中给定

现在,我并不急于改变CWebUser(事实上,在已经扩展的类中改变它,在其他方面稍微改变了它),因为我担心这会对它产生意想不到的影响。系统。

任何人都可以为此加油吗?

你会做什么?

谢谢!

环境:


// Yii v1.1.15
// session component configuration: (but believe me, I've tried every 
// combination - its not really related. Check CWebUser.init()...)
'session' => array(
            'class' => 'CHttpSession',
            'autoStart' => false,
            'sessionName' => 'MY_COOKIE_NAME',
            'cookieMode' => 'allow',
            'cookieParams' => ['lifetime' => 1000],
            'gcProbability' => 33,
            'timeout' => 1000,
            'savePath' => '/tmp/',
        ),
// Web User's _allowAutoLogin_ is set on 'false'

2 个答案:

答案 0 :(得分:1)

因此,您需要检查用户是否已登录(这就是您使用isGuest的原因),但您不想使用会话?

方法isGuest使用会话变量来检查用户是否已登录。会话在创建CWebUser时打开。 (在您所说的init方法中。)isGuestCWebUser类的一部分。如果要调用此方法,它将始终创建会话。除非你覆盖它。

我认为你可以采取两种方式:

  1. 打开会话,检查用户是否已登录(isGuest),然后仅在用户未登录时关闭它。您需要覆盖isGuest方法。在需要时覆盖任何其他方法以打开会话。 (登录/寄存器)
  2. 让客户端在每次请求时发送其登录数据,这样您就不必检查会话,因此不必打开它。
  3. 在这两种情况下,您都需要覆盖CWebUser.init(),以便在创建CWebUser时无法打开会话。

答案 1 :(得分:0)

所以基本上这需要来自以下需求集:

  • Yii将(也)用作RESTful API服务器。
  • RESTful服务器将在成功登录后建立会话
  • 上述最后一点意味着访客用户没有会话cookie,而只存在经过身份验证的用户会话。

以上的优点?主要是库存PHP会话对登录会话的“免费”管理,包括超时,垃圾收集等。

尽管这种设计最初吸引人,但缺点克服了优势:

  • 的确,isGuest是CWebUser的一个属性,经过测试,已经暗示为请求生成了一个会话。
  • 试图改变上述行为引入了许多问题和错误,上帝知道潜藏着什么。本质上,试图在Yii v1.1.x上改变这种行为是有问题的,因为基于Yii的应用程序的许多内置特性和行为(在抽象意义上......)隐含地使用已建立的会话。

所以,我恢复了以下设计:

  • Yii的会话管理被还原为股票 - 是的,请!为一切事情打开会议! (就像你平常那样做得好)。
  • RESTful服务器在成功登录调用时发送显式会话令牌。
  • 客户端需要保存此令牌并使用每个需要经过身份验证的会话的API方法显式发送。
  • 服务器端将会话令牌保存在“自由管理”(PHP)会话中,因此能够在每个不同的请求上验证具有 PHP会话的用户的令牌确实是他的,并且有效。