满足用户查看登陆记录的需求,需要把用户的登陆行为捕捉并记录下来。正常的用户登陆在用户登陆的action里面捕捉即可,问题在于使用cookie登陆的捕捉。

YII默认启用了基于COOKIE的登陆方式,在protected/config/main.php下。为了提升用户体验,开启自动登陆也是合理的。但是自动登陆的行为不触发在controller里面的action方法,比如site/login。如果在这里写逻辑记录用户登陆,对于cookie方式则失效。失去了cookie方式的登陆记录,显然这是实现缺陷。

两种解决方案

  1. 禁用YII的自动登陆,自己实现基于COOKIE登陆。禁用YII的自动登陆只需在protected/main.php里面将component下的user的allowAutoLogin属性设置为false即可。自己实现基于COOKIE的登陆也比较简单,例如可以在一个基类的controller里重写beforeAction方法,或者定义filters方法,对用户进行认证登陆。
  2. 第二种方法是派生出CWebUser类,实现afterLogin方法。追踪YII的自动登陆流程,发现YII的登陆的时候会在CWebUser下触发afterLogin方法。不管是哪种认证方式,基于YII的用户体系流程都会走到这里。所以我们只需实现这个方法即可。

实践

由于第二种方法比较优雅,也符合YII的流程,所以推荐采用这种方式实现对用户登陆行为的捕捉。查看API发现afterLogin方法的原型如下:

protected afterLogin($fromCookie)

其中$fromCookie是boolean类型,指示是否通过cookie自动登陆。这个参数满足了我们捕捉自动登陆或者手动登陆的要求。于是步骤如下:

  1. 新建WebUser类。在protected/components/文件夹下面建立WebUser.php,让其集成自CWebUser:
< ?php
class WebUser extends CWebUser
{
    public function afterLogin($fromCookie)
    {
        // do something
    }
}
  1. 让应用使用自定义的WebUser来实例化user对象。打开protected/configs/main.php,将user的配置变更为:
    'user' => array(
        'class' => 'application.components.WebUser',
        'allowAutoLogin' => 'true',
        'loginUrl' => array('/user/login'),
    ),

通过上述步骤,就能实现了对用户登陆类型的记录和监控。例如像淘宝之类的安全级别较高,当用户是自动登陆的时候,进行交易的时候需要确认登陆密码。在派生出来的webuser里面可以方便的实现这些功能和逻辑。

参考

yii用户自动登录流程