同福

做个用户管理系统(32)——忘记密码之验证用户信息【20201221】

介绍

介绍

福哥今天带着大家完成TFUMS系统的忘记密码功能的第一步——验证用户信息。因为用户数据表里userName和userEmail都是唯一的,它们都可以作为忘记密码的验证手段。而userEmail是需要登录后进行绑定邮箱才会产生的,也就是说它不一定是存在的。

综上所述,福哥决定userName和userEmail都要验证,只要其中一个验证通过了就可以了。由于userName是一定存在的,所有福哥优先验证userName。

还有一个问题,邮箱的特点是包含一个“@”字符的,为了避免有人拿邮箱作为用户名注册的冲突问题,福哥还要在注册地方限制用户名不能包含“@”字符才行。

手机号码注册是一个很主流的设计,福哥今后会添加绑定手机号码的功能,手机号码也会成为忘记密码的验证手段,所以用户名也不能是一个手机号码。

注册接口控制器

福哥在注册接口控制器里增加了对用户名的格式的判断逻辑。

if(preg_match("/[\`\!\@\#\$\%\^\&\*\(\)\-\_\+\=\|\\\{\}\[\]\:\;\"\'\<\>\,\.\?\/]/", $userName)){

    return $this->tfphp->getResponse()->responseJSON_CM(200, 1001001, "用户名不能包含特殊符号");
}
if(preg_match("/^1\d{10}$/", $userName)){

    return $this->tfphp->getResponse()->responseJSON_CM(200, 1001001, "用户名不能是手机号码");
}

注册视图模板

福哥在注册视图模板里也增加了对用户名的格式的判断逻辑。

[
    {type:"empty", name:"user", msg:"请填写用户名"},
    {type:"min", value:2, name:"user", msg:"用户名最少2个字"},
    {type:"max", value:20, name:"user", msg:"用户名最多20个字"},
    {type:"mre", value:/[\`\!\@\#\$\%\^\&\*\(\)\-\_\+\=\|\\\{\}\[\]\:\;\"\'\<\>\,\.\?\/]/, name:"user", msg:"用户名不能包含符号"},
    {type:"mre", value:/^1\d{10}$/, name:"user", msg:"用户名不能是手机号码"},
    {type:"empty", name:"pass", msg:"请填写密码"},
    {type:"min", value:6, name:"pass", msg:"密码最少6个字"},
    {type:"empty", name:"confirmPass", msg:"请填写确认密码"},
    {type:"empty", name:"vsn", msg:"请填写验证码"},
]

模型user

forgot

public function forgot(string $user):?string {
    $myAES = new TFAES($this->tfphp);

    if(strpos("@", $user) !== false){
        $userInfo = $this->getByTable("userByEmail", array($user));
    }
    else{
        $userInfo = $this->getByTable("userByName", array($user));
    }
    if($userInfo != null){
        $userInfoData = serialize(array('userID'=>$userInfo['userID'],'userName'=>$userInfo['userName'],'userEmail'=>$userInfo['userEmail']));
        $userInfoDataEncrypted = $myAES->encrypt($userInfoData, TFConfig::get("projectAESPK", "system"). date("YmdH0000"), "");

        return $userInfoDataEncrypted;
    }

    return null;
}

验证用户信息接口

user_process

protected function user_process(){
    $req = $this->tfphp->getRequest();
    $post = $req->post;
    $user = new user($this->tfphp);
    $userName = $post->get("user");

    try{
        // request test
        if($userName == ""){

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

        // forgot user
        $ret = $user->forgot($userName);
        if($ret != null){

            return $this->tfphp->getResponse()->responseJSON_CM(200, 0, "OK", array('sn'=>$ret));
        }
        else{

            return $this->tfphp->getResponse()->responseJSON_CM(200, 1001082, "找不到匹配的用户");
        }
    }
    catch(\TypeError $e){

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

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

验证用户信息模板

HTML代码

<!-- forgot form begin -->
<div class="row login-form">
    <div class="col-sm-12">
        <h3 class="text-center">忘记密码</h3>
        <p>请输入正确的用户名或者邮箱地址</p>
        <form action="forgotWay.htm">
            <div class="form-group">
                <label>用户名/邮箱地址</label>
                <input class="form-control" type="text" name="user" />
            </div>
            <div class="form-group">
                <button class="btn btn-primary btn-sm form-control">下一步</button>
            </div>
        </form>
    </div>
</div>
<!-- forgot form end -->

JS代码

$('form').form({
    url: "api/member/forgot",
    method: "post",
    validations: [
        {type:"empty", name:"user", msg:"请填写用户名或者邮箱地址"},
    ],
    onSuccess: function (d) {
        if(d.errcode == 0){
            document.location = '<% $TFReq->server->BASE_URI %>forgotWay.htm?sn='+d.sn;
        }
        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();
    }
});

讲解

模型user

forgot

这里判断了如果用户名包含“@”就当作邮箱地址处理,否则就当作用户名处理。

验证用户信息接口

user_process

标准的表单处理程序,使用模型user的forgot方法验证用户信息。

验证用户信息模板

HTML

表单只有一个用户名的输入框,可以输入用户名或者邮箱地址。

JS

标准的表单JS驱动程序,处理成功的话会从返回数据里面拿到sn串缀到forgotWay.htm后面跳转过去。

效果

83a9cae9021ee28b.jpg

总结

福哥今天带着童鞋们完成了忘记密码功能的第一步——验证用户信息表单的功能。这里面引出了注册用户名的格式限制的问题,为了避免冲突,我们又在用户注册的地方限制了用户名不能包含“@”字符,也不能是一个手机号码。

像这样的返工是不可避免的,在快速生产的现如今,不会有太多时间让我们仔细去推敲的。所以,大家要坦然看待返工的问题,真正的互联网公司的研发团队每天不返工才是不正常的。为什么?可以去问问产品经理去,哈哈哈~~

下一课,我们继续开发忘记密码功能,记得来看哦~~