Typecho作为一款轻量级的个人博客程序,它设计的时候是打算让用户前端浏览页面,而管理员登陆以后则会跳转到后台的管理页面,这样设计对于纯个人博客而言是足够的。可是现在很多人会需要Typecho在浏览的基础上,加上一些权限控制,例如一些只能登陆以后才能浏览的页面。这样就显示出typecho登录设计模式的不足了,因为先跳转到前台这样子的操作会很影响浏览体验,我们希望实现的效果是用户可以直接前台登录,当输入登录信息以后,直接在当前页面刷新登录信息。
原版Typecho登录逻辑
首先我们应该了解,Typecho处理登录代码的文件在哪里,通过研究我们可以知道 var\Widget\Login.php这个文件实现了我们的登录请求处理,我们先把这个文件打开,将处理登录逻辑的代码部分说明一下。
public function action()
{
// protect
$this->security->protect();
/** 如果已经登录 */
if ($this->user->hasLogin()) {
/** 直接返回 */
$this->response->redirect($this->options->index);
}
/** 初始化验证类 */
$validator = new Validate();
$validator->addRule('name', 'required', _t('请输入用户名'));
$validator->addRule('password', 'required', _t('请输入密码'));
$expire = 30 * 24 * 3600;
/** 记住密码状态 */
if ($this->request->remember) {
Cookie::set('__typecho_remember_remember', 1, $expire);
} elseif (Cookie::get('__typecho_remember_remember')) {
Cookie::delete('__typecho_remember_remember');
}
/** 截获验证异常 */
if ($error = $validator->run($this->request->from('name', 'password'))) {
Cookie::set('__typecho_remember_name', $this->request->name);
/** 设置提示信息 */
Notice::alloc()->set($error);
$this->response->goBack();
}
/** 开始验证用户 **/
$valid = $this->user->login(
$this->request->name,
$this->request->password,
false,
1 == $this->request->remember ? $expire : 0
);
/** 比对密码 */
if (!$valid) {
/** 防止穷举,休眠3秒 */
sleep(3);
self::pluginHandle()->loginFail(
$this->user,
$this->request->name,
$this->request->password,
1 == $this->request->remember
);
Cookie::set('__typecho_remember_name', $this->request->name);
Notice::alloc()->set(_t('用户名或密码无效'), 'error');
$this->response->goBack('?referer=' . urlencode($this->request->referer));
}
self::pluginHandle()->loginSucceed(
$this->user,
$this->request->name,
$this->request->password,
1 == $this->request->remember
);
/** 跳转验证后地址 */
if (!empty($this->request->referer)) {
/** fix #952 & validate redirect url */
if (
0 === strpos($this->request->referer, $this->options->adminUrl)
|| 0 === strpos($this->request->referer, $this->options->siteUrl)
) {
$this->response->redirect($this->request->referer);
}
} elseif (!$this->user->pass('contributor', true)) {
/** 不允许普通用户直接跳转后台 */
$this->response->redirect($this->options->profileUrl);
}
$this->response->redirect($this->options->adminUrl);
}