创新实训(三)系统用户登录功能

登录功能

通过账号和面码登录网站是最基本的功能之一,登录功能的实现主要在文件login.php文件中,下面是具体的介绍。
这个系统的登录功能通过一个PHP脚本实现,该脚本包含处理用户登录表单提交的函数和前端登录表单。以下是系统登录功能的详细介绍:

1. 登录处理函数

函数 handleLoginPost 处理用户提交的登录表单的POST请求,具体流程如下:

  • CSRF检查:首先检查CSRF token,以防止跨站请求伪造。如果检查失败,返回“expired”。
  • 表单字段验证:检查表单是否包含usernamepassword字段,如果缺少任何一个字段,返回“failed”。
  • 字段值获取:从表单中获取usernamepassword的值。
  • 字段值验证
    • 验证用户名是否合法,若不合法返回“failed”。
    • 验证密码是否合法,若不合法返回“failed”。
  • 用户验证
    • 通过 queryUser 函数查询用户名对应的用户信息,如果用户不存在或密码不匹配(通过 checkPassword 函数检查),返回“failed”。
    • 检查用户是否被封禁(用户组为'B'),若被封禁返回“banned”。
  • 用户登录:使用 Auth::login 函数登录用户。
  • 返回结果:登录成功返回“ok”。

代码片段

function handleLoginPost() {
    if (!crsf_check()) {
        return 'expired';
    }
    if (!isset($_POST['username']) || !isset($_POST['password'])) {
        return "failed";
    }
    $username = $_POST['username'];
    $password = $_POST['password'];
    
    if (!validateUsername($username) || !validatePassword($password)) {
        return "failed";
    }
    
    $user = queryUser($username);
    if (!$user || !checkPassword($user, $password)) {
        return "failed";
    }
    
    if ($user['usergroup'] == 'B') {
        return "banned";
    }
    
    Auth::login($user['username']);
    return "ok";
}

2. 页面跳转和登录请求处理

  • 已登录用户重定向:如果用户已登录(通过 Auth::check 函数检查),重定向至首页。
  • 处理登录请求:如果收到POST请求并且包含login字段,调用 handleLoginPost 函数处理登录,并输出结果后终止脚本执行。

代码片段

// 如果账号存在,直接重定向至首页
if (Auth::check()) {
    redirectTo('/');
}

if (isset($_POST['login'])) {
    echo handleLoginPost();
    die();
}

3. 前端登录表单

HTML表单和JavaScript代码用于处理前端的用户交互:

  • 表单结构:表单包括用户名和密码的输入字段,用户提交表单后触发JavaScript代码进行验证和提交。
  • 表单提交处理:提交表单时,先进行客户端验证,包括用户名和密码的验证。如果所有验证通过,使用AJAX POST请求提交表单数据到服务器。

HTML表单代码片段

<form id="form-login" class="form-horizontal" method="post">
  <div id="div-username" class="form-group">
    <label for="input-username" class="col-sm-2 control-label"><?= UOJLocale::get('username') ?></label>
    <div class="col-sm-3">
      <input type="text" class="form-control" id="input-username" name="username" placeholder="<?= UOJLocale::get('enter your username') ?>" maxlength="20" />
      <span class="help-block" id="help-username"></span>
    </div>
  </div>
  <div id="div-password" class="form-group">
    <label for="input-password" class="col-sm-2 control-label"><?= UOJLocale::get('password') ?></label>
    <div class="col-sm-3">
      <input type="password" class="form-control" id="input-password" name="password" placeholder="<?= UOJLocale::get('enter your password') ?>" maxlength="20" />
      <span class="help-block" id="help-password"></span>
    </div>
  </div>
  <div class="form-group">
    <div class="col-sm-offset-2 col-sm-3">
      <button type="submit" id="button-submit" class="btn btn-secondary"><?= UOJLocale::get('submit') ?></button>
    </div>
  </div>
</form>

JavaScript代码片段

function validateLoginPost() {
    var ok = true;
    ok &= getFormErrorAndShowHelp('username', validateUsername);
    ok &= getFormErrorAndShowHelp('password', validatePassword);
    return ok;
}

function submitLoginPost() {
    if (!validateLoginPost()) {
        return false;
    }
    
    $.post('/login', {
        _token : "<?= crsf_token() ?>",
        login : '',
        username : $('#input-username').val(),
        password : md5($('#input-password').val(), "<?= getPasswordClientSalt() ?>")
    }, function(msg) {
        if (msg == 'ok') {
            var prevUrl = document.referrer;
            if (prevUrl == '' || /.*\/login.*/.test(prevUrl) || /.*\/logout.*/.test(prevUrl) || /.*\/register.*/.test(prevUrl) || /.*\/reset-password.*/.test(prevUrl)) {
                prevUrl = '/';
            };
            window.location.href = prevUrl;
        } else if (msg == 'banned') {
            $('#div-username').addClass('has-error');
            $('#help-username').html('该用户已被封停,请联系管理员。');
        } else if (msg == 'expired') {
            $('#div-username').addClass('has-error');
            $('#help-username').html('页面会话已过期。');
        } else {
            $('#div-username').addClass('has-error');
            $('#help-username').html('用户名或密码错误。');
            $('#div-password').addClass('has-error');
            $('#help-password').html('用户名或密码错误。<a href="/forgot-password">忘记密码?</a>');
        }
    });
    return true;
}

$(document).ready(function() {
    $('#form-login').submit(function(e) {
        e.preventDefault();
        submitLoginPost();
    });
});

另外还用到了一些其他包或类里的函数,如 Auth::checkAuth::loginqueryUsercheckPasswordvalidateUsernamevalidatePasswordcrsf_check 等。
下面是实际的效果展示:
image
密码输入失败后会进行提示
image
登陆成功后会直接跳转到主页

posted @   贺丁  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示