做个用户管理系统(20)——登录功能的实现【20201207】

发表于 2020-12-07 14:13:45
阅读 87

介绍

介绍

福哥今天就带着大家完成TFUMS系统的登录功能,为什么登录功能不分几集?因为在注册功能开发的过程中我们已经把表单需要准备的工具和接口都弄好了,所以今天在制作登录功能的时候一集就可以做完了。

登录功能就是检验用户输入的用户名和密码是否正确,如果用户名和密码是正确的,就建立一个token。这个token里包含这登录用户的信息,但是一般人拿到这个token是没有用的,只有服务器才能通过token找出对应的用户信息。token是一段MD5的哈希字符串,它本身没有任何意义,它在服务器上做为一个Redis数据库缓存的键名存在,它是有有效期的。

token是实现维持登录状态的关键,在服务器上token是Redis的数据库的键名,在客户端上token是Cookie的键值。

登录功能

页面控制器

use TFPHP\Controller\Page\TFController;

class PageController extends TFController{
    protected function process(){

    }
}

接口控制器

protected function process(){
    $req = $this->tfphp->getRequest();
    $mySafeCode = new TFSafeCode($this->tfphp);
    $user = new user($this->tfphp);
    $post = $this->tfphp->getRequest()->post;
    $cookie = $this->tfphp->getRequest()->cookie;
    $userName = $post->get("user");
    $userPass = $post->get("pass");
    $remember = $post->get("remember");
    $vsn = $post->get("vsn");
    $sn = $cookie->get("safeCode_login");

    // verify code
    if(!$mySafeCode->verify($sn, $vsn)){

        return $this->tfphp->getResponse()->responseJSON_CM(200, 1001004, "验证码错误");
    }

    // request test
    if($userName == "" || $userPass == ""){

        return $this->tfphp->getResponse()->responseJSON_CM(200, 1001001, "错误请求");
    }

    // authorize user
    $ret = $user->auth($userName, $userPass);
    switch ($ret){
        case 1:
            return $this->tfphp->getResponse()->responseJSON_CM(200, 1001002, "用户名不存在");
            break;
        case 2:
            return $this->tfphp->getResponse()->responseJSON_CM(200, 1001003, "密码错误");
            break;
        case 3:
            return $this->tfphp->getResponse()->responseJSON_CM(200, 1001003, "用户被锁定");
            break;
    }
    $userId = $user->getLastUserID();

    // create token
    $token = $user->createToken($userId, ($remember == "Y") ? true : false);
    $cookieExpires = ($remember == "Y") ? time()+60*60*24*7 : time()+60*60*8;
    $cookie->setCookie("tfums_id", $userId, $cookieExpires, $req->server->get("BASE_URI"));
    $cookie->setCookie("tfums_token", $token, $cookieExpires, $req->server->get("BASE_URI"));

    // output
    return $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK", array(
        'userid'=>$userId,
    ));
}

视图模板HTML

<!-- login form begin -->
<div class="row login-form">
    <div class="col-sm-12">
        <h3 class="text-center">登录</h3>
        <p>请输入正确的用户名和密码登录用户管理系统</p>
        <form>
            <div class="form-group">
                <label>用户名</label>
                <input class="form-control" type="text" name="user" />
            </div>
            <div class="form-group">
                <label>密码</label>
                <input class="form-control" type="password" name="pass" />
            </div>
            <div class="form-group">
                <label>验证码</label>
                <div style="overflow: hidden; vertical-align: middle;">
                    <input class="form-control form-vsn" type="text" name="vsn" style="float: left;" />
                    <img id="safecode" style="display: none; float: left; margin-left: 6px;" />
                    <a id="safecode-refresh" href="JavaScript:void(0)" style="float: left; margin-left: 6px; margin-top: 6px;">看不清?换一个!</a>
                </div>
            </div>
            <div class="form-group overflow-hidden">
                <label class="float-left">
                    <input type="checkbox" name="remember" value="Y" />
                    保存登录状态
                </label>
                <a href="" class="float-right">忘记密码</a>
            </div>
            <div class="form-group">
                <button class="btn btn-primary btn-sm form-control">登录</button>
            </div>
        </form>
    </div>
</div>
<!-- login form end -->

视图模板JS

// form
$('form').form({
    url: "api/member/login",
    method: "post",
    validations: [
        {type:"empty", name:"user", msg:"请填写用户名"},
        {type:"min", value:2, name:"user", msg:"用户名最少2个字"},
        {type:"max", value:20, name:"user", msg:"用户名最多20个字"},
        {type:"re", value:/^[^\`\~\!\@\#\$\%\^\&\*\(\)\[\]\{\}\-\_\+\|\\\:\;\"\'\<\>\,\.\?\/]/, name:"user", msg:"用户名不能以符号开头"},
        {type:"empty", name:"pass", msg:"请填写密码"},
        {type:"min", value:6, name:"pass", msg:"密码最少6个字"},
        {type:"empty", name:"vsn", msg:"请填写验证码"},
    ],
    onSuccess: function (d) {
        if(d.errcode == 0){
            document.location = '<% $TFReq->server->BASE_URI %>';
        }
        else{
            if(d.errcode == 1001004){
                $('form').tips({
                    text:"验证码错误"
                });
                $('#safecode-refresh').trigger('click');
            }
            else{
                $('form').tips({
                    text:d.errmsg
                });
            }
        }
    },
    onError: function (d) {
        $('form').tips({
            text:"服务器响应错误"
        });
    },
    onValidationError: function (form, name, msg) {
        $('form').tips({
            text:msg
        });
        $('form').find('[name="'+ name +'"]').focus();
    }
});
$('#safecode-refresh').click(function () {
    $('#safecode').attr('src', "<% $TFReq->server->BASE_URI %>api/image/safeCode?key=login&rnd="+Math.random());
    $('#safecode').show();
});
$('#safecode-refresh').trigger('click');

讲解

页面控制器

页面控制器里面暂时没有任何代码。

接口控制器

首先进行验证码的校验,这个和注册功能是一样的。

接着检查输入数据是否正确。

再来就是使用模型user的auth方法检验用户输入的用户名和密码是否正确。

最后就是使用模型user的createToken方法创建一个token,这个token存储在Redis数据库里面。而后我们还将这个token存进了Cookie里面。

视图模板HTML

这个是我们之前设计好的模板,不同之处在于福哥加入了和注册功能一样的验证码。

视图模板JS

这个JS是通过注册功能的JS代码改造而来的,两边的代码区别不大,稍微改改就可以用了。

1f96f1b0e07e070a.jpg

总结

福哥今天带着童鞋们完成了TFUMS系统的登录功能,这个登录功能基本上都是通过注册功能的代码复制过来稍加改动完成的。其实来说不仅仅是登录功能,其他功能也可以通过注册功能改一改,无非就是表单项目不一样,表单验证条件不一样,处理程序不一样。

下一课,福哥将带着大家来实现个人资料修改的功能,这个不需要纠结为什么和制作模板的顺序不一样的问题,福哥会根据实际情况进行调整。