标签归档:onUserLoadFromSession

Mediawiki 登录操作

Mediawiki是一个广泛使用的wiki系统之一。

整个wiki的搭建过程十分的简便,几乎是各种下一步的傻瓜安装方式。安装时在有Memcached的机器的前提下,强烈建议配置上Memcached,在配与不配Memcached这个选项上,配置了Memcached之后速度会有明显的提升。

在使用wiki的过程中,可能我们需要对外公开wiki的内容,但是不能让未授权用户编辑的情况,这时候就需要使用认证。在官方网站上有很多的认证插件可以选择,不过有时需要加入自己使用的wiki系统的一些特性的时候(比如用公司的统一登录接口),插件就不一定适用了,需要自己编写插件。

基本信息

下面是Mediawiki默认的user表表结构,在下文中对于表字段的操作依据都来源于下方:

插件编写

关于插件的编写,可以首先看看官网上对于认证插件的说明,自己尝试编写了两种登录的方式,一种是通过继承 AuthPlugin 类并重写 authenticate 方法实现,另一种是编写 UserLoadFromSession 的对应处理方法处理利用现有的Cookie进行登录的方法。第一种方法个人觉得适合使用同一登录的情况下使用,第二种方法适合wiki与提供认证的服务处于同域的情况下使用,实现同步登录。

重写 authenticate 方法

首先我们要做的就是继承 AuthPlugin 类,并且将标记认证对象的全局变量 $wgAuth 设定为一个这一类型的对象。

参见 AuthPlugin 类中 authenticate 方法的定义:

需要实现的就是一个传入用户名密码并在验证之后返回结果的方法。用户在wiki点击登录动作发送来的用户名密码将会在这个方法中得到认证,利用使用公司邮箱密码登录,利用统一的LDAP登录接口获取数据,判断是否登录成功。

对于登录成功的,应当返回 true,登录不成功的,应当返回 false

但是,在使用外部确认的登录方式的情况下,仍然需要在wiki数据库中的 WIKI_TABLE_PREFIX_user 表中建立用户(WIKI_TABLE_PREFIX_ 表示是),在认证通过之后,需要构建一个 User 类的对象,并且将表示当前登录用户的全局变量 $wgUser 设定为生成的User类对象。例如登录成功之后返回用户的用户名,假设用户名是唯一的情况下,可以在数据库中检索出相关的数据,构建用户对象。

启用这一方式进行登录验证还需要在wiki代码根目录下的 LocalSettings.php 文件中引入这一文件(根据实际位置决定)。

如果是想要将wiki通过iframe形式加入其它页面的,记得还需要在 LocalSettings.php 中设定

Mediawiki默认是不允许wiki被iframe加载的。

用如下代码大致可以表示整个方法的实现:

编写 UserLoadFromSession 的对应处理方法

在请求数据的过程中, 通过注册到 $hooks 中的方法,可以进行进行验证($hooks 参见官方说明,是Mediawiki中可以让用户自定义方法在特定情况下使用的机制),对于这个方法,名称可以任意取,但是参数必须为:

即传入一个 User 类的对象和一个标记用户是否已登录的布尔值,其中布尔值用于确定用户登录状态。

此方法的返回值,官方文档建议一直返回 true (即In any case, return true)。

对于判定用户是否登录,在同域的情况下,自己尝试的思路是检查Cookie中是否带有指定的字段信息,例如token值以及用户名,将其与数据库中的数据进行比对,通过则构建一个用户对象并将其赋值给 $wgUser 全局变量。

可以在上述类中添加如下代码完成功能:

这里需要注意token是应当有超时的,我的处理方式是在user表中增加如下一个字段来记录超时的时间戳:

通过在取回token的同时取回超时时间戳,并与当前时间戳做对比,若当前时间戳小于超时,则认定未过期。

如果需要实现同步登录状态,那么在还需要在主要的登录环境中在退出时,取消用户登录状态,例如将token字段置空,这样可以标记用户已经退出。同时也要对直接从wiki登录的用户做处理,可以针对 UserLogout 这个hook编写一个处理方法,名称任意,在这一处理方法中将token字段置空。在这里需要在代码中注册 UserLoadFromSession 以及 UserLogout 对应的处理方法:

可以考虑使用Redis或者Memcached缓存token等信息,并且设定上数据超时,能减少数据库访问并且相应速度更快。