原创Typecho

Typecho无需插件实现前端登录,提升用户体验

本文阅读 6 分钟
首页 Typecho 正文

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);
    }

通过action方法里面可以看出,所有对于登录请求的相应,都是从$this->response->redirect()这个方法返回的,那么我们要实现前端登录的话,就要对这个返回的方法进行修改,以便我们可以实现typecho前端登录的效果。

实现Typecho前端登录逻辑

找到了typecho登录请求处理方法以后,我们要修改登录处理逻辑就很简单了。我们先以第一段判断用户是否已经登录的代码来作为演示,原来的代码处理是:

        /** 如果已经登录 */
        if ($this->user->hasLogin()) {
            /** 直接返回 */
            $this->response->redirect($this->options->index);
        }
我们这里就需要使用别的方式返回,这里我先直接贴出解决方法,然后再给大家讲解原理。我们需要把前面代码修改成:
/** 如果已经登录 */
        if ($this->user->hasLogin()) {
            /** 直接返回 */
            $msg=array('code'=>2,'msg'=>'用户已经登录了,请勿重复登录!');
            echo json_encode($msg);
            exit;
            $this->response->goBack();
        }

这里我们把重定向返回改成了自己的代码,首先我们先设置一下需要返回的信息,然后通过exit退出,最后再通过$this->response->goBack();方法返回。至于为什么这样做就可以实现返回前端的效果,具体可以参考我另外一篇文章:typecho实现自定义路由的各种办法,里面有详细说明typecho实现自定义路由和处理ajax请求的经验。
能够实现处理typecho的请求以后,前端页面处理就非常简单了,例如我们可以通过bootstrap实现一个模态对话框,当输入登录信息以后,通过ajax发送登录请求,然后通过返回的数据信息判断用户是否成功登录。具体代码就不贴了,后面我会找一个好看点的模板来给大家详细的演示,并且会贴出完整的实现代码。

完善Typecho前端登录

其实上面的处理代码,在实际应用中还是有缺陷的,这个也是我在改自己最近做的一个项目中发现的,那就是当typecho把所有的登录请求都当成前端登陆以后,管理员登录以后要跳转到后台也不行了,这个问题解决起来也并不困难,通过研究Typecho源码发现,我们可以通过$this->request->isAjax()这个方法来判断请求类型,如果是前端的ajax请求,我们则返回数据给前端,如果是正常管理员的登录,我们则跳转到管理员后台。因此更加完善的typecho前端登录代码就出来了

/** 如果已经登录 */
        if ($this->user->hasLogin()) {
            /** 直接返回 */
            if($this->request->isAjax()){
                $msg=array('code'=>2,'msg'=>'用户已经登录了,请勿重复登录!');
                echo json_encode($msg);
                exit;
                $this->response->goBack();
            }else{
                /** 直接返回后台首页 */
                $this->response->redirect($this->options->index);
            }
        }

当然前端登录这部分我只演示了用户是否已经登录部分,至于后面用户名密码是否正确等等判断,方法都是一样的,都是在相关判断的位置修改登录逻辑的处理代码即可。同样的,typecho实现前端注册我们一样可以实现,虽然说注册的代码判断位置会更多一些,但是对于数据返回的处理逻辑是一模一样的,我们可以轻松的做到触类旁通。

原创文章,作者:努力的牛奋,如若转载,请注明出处:https://mokev.com/1.html
FFmpeg轻松制作随机文字移动效果教程
下一篇 » 03-14

热门文章

标签TAG

没有任何标签