创新实训(三)系统用户登录功能
登录功能
通过账号和面码登录网站是最基本的功能之一,登录功能的实现主要在文件login.php文件中,下面是具体的介绍。
这个系统的登录功能通过一个PHP脚本实现,该脚本包含处理用户登录表单提交的函数和前端登录表单。以下是系统登录功能的详细介绍:
1. 登录处理函数
函数 handleLoginPost
处理用户提交的登录表单的POST请求,具体流程如下:
- CSRF检查:首先检查CSRF token,以防止跨站请求伪造。如果检查失败,返回“expired”。
- 表单字段验证:检查表单是否包含
username
和password
字段,如果缺少任何一个字段,返回“failed”。 - 字段值获取:从表单中获取
username
和password
的值。 - 字段值验证:
- 验证用户名是否合法,若不合法返回“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::check
、Auth::login
、queryUser
、checkPassword
、validateUsername
、validatePassword
、crsf_check
等。
下面是实际的效果展示:
密码输入失败后会进行提示
登陆成功后会直接跳转到主页
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端