PHP 会话控制与 PDO 实战
实战主要内容
- 1.登录页面设计与登陆后首页设计
- 2.登录页面验证用户输入的用户名与密码是否与数据库中数据一致
- 数据库中的密码使用 md5 加密保存
- 3.登录页面检测用户是否选择 7 天自动登录 并生成相应的 cookie
- 本地 cookie 不直接保存用户密码 使用令牌加密存储密码数据
- 4.登录页面检测本地是否有 7 天自动登录的 cookie 如有验证密码后直接进入首页
- 5.首页展示用户名信息与退出登录选项
页面设计
登录页面设计成 2 个页面:
- 当本地 cookie 中的用户名与令牌能与数据库中的数据验通过使用免登录提示页面
<?php
require"check_cookie.php";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<style>
form{
margin: 60px auto;
max-width: 400px;
height: 110px;
border: 5px solid green;
display: flex;
flex-flow: column nowrap;
align-items: center;
}
form > input{
width: 280px;
height: 40px;
margin: 10px;
background-color: white;
border: 1px solid green;
}
</style>
</head>
<body>
<form action="" method="post" >
<input type='submit' name='old_account' value='使用<?php echo $username;?>账号登录' />
<input type='submit' name='new_account' value='使用新账号登录' />
</form>
</body>
</html>
- 当本地 cookie 中的用户名与令牌能与数据库中的数据验不通过使用用户名密码登录页面
<?php
require"check_userInfo.php";
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<style>
.login{
margin: 60px auto;
max-width: 400px;
height: 250px;
border: 5px solid green;
display: flex;
flex-flow: column nowrap;
}
.login > h1{
font-size: 20px;
margin: 10px;
text-align: center;
}
.login > form{
display: flex;
flex-flow: column nowrap;
align-items: center;
}
.login > form > *{
width: 280px;
height: 40px;
margin: 10px;
}
.login > form > div{
display: flex;
justify-content: space-between;
}
.login > form > div > input{
width: 100px;
background-color: white;
border: 1px solid green;
}
.login > form > div > div{
font-size: 12px;
line-height: 40px;
}
</style>
</head>
<body>
<div class="login">
<h1>用户登录</h1>
<form action="" method="post">
<input type="text" name="username" placeholder="用户名" required>
<input type="text" name="password" placeholder="密码" required>
<div>
<div><input type="checkbox" name='chk'>7天自动登录</div>
<input type="submit" name="sub">
</div>
</form>
</div>
</body>
</html>
首页展示用户名信息与退出登录选项已经退出选项下的脚本
<?php
require"check_cookie.php";
if(!empty($_POST['out'])){ //用户选择退出登录
//跳转到登录界面
//清空先用户的cookie
setcookie('username', '', 0);
setcookie('auth', '', 0);
exit("<script> location.href = 'login_new.php'; </script>");
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
<style>
body{
display: flex;
flex-flow: column nowrap;
text-align: center;
}
form > *{
margin: 15px;
}
</style>
</head>
<body>
<h1>首页</h1>
<form action="" method="post">
<span>欢迎您:<?php echo $username; ?></span>
<input type="submit" name="out" value="退出登录">
</form>
</body>
</html>
PHP 脚本
设计检测用户输入的用户名与密码与数据库中的数据进行验证的脚本
<?php
if(!empty($_POST['sub'])){
$username = $_POST['username'];
$password = md5($_POST['password']);
$chk = $_POST['chk'];
//连接数据库
require "config.php";
//利用用户输入的信息查询数据库
$sql = "SELECT `id` FROM `tb_member` WHERE `username`=? AND `password`=?";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1, $username);
$stmt->bindParam(2, $password);
$stmt->execute();
//用户名而且密码正确
if($stmt->rowCount() == 1){
//获取用户id数据
$res = $stmt->fetch(PDO::FETCH_ASSOC);
//清空先前用户的cookie
setcookie('username', '', 0);
setcookie('auth', '', 0);
//准备写入新用户的cookie
//加盐操作
$salt = 'php.cn';
//生成验证令牌
$auth = md5($username.$password.$salt).','.$res["id"];
//用户勾选7天免登录
if(!empty($chk)){
setcookie('username', $username, strtotime('+7 days'));
setcookie('auth', $auth, strtotime('+7 days'));
}else{//用户没有勾选7天免登录 临时cookie
setcookie('username', $username);
setcookie('auth', $auth);
}
//跳转到首页
exit("<script>
alert('登陆成功!');
location.href = 'index.php';
</script>");
}else{
//用户名或密码错误
exit("<script>
alert('用户名或密码错误!');
location.href = 'login_new.php';
</script>");
}
}
- 设计检测本地 cookie 与数据库中的数据进行验证的脚本(0717 作业)
<?php
//检测本地cookie是否包含用户名与令牌
if(isset($_COOKIE['username']) && isset($_COOKIE['auth'])){
//将字符串以,来分割成数组
$res = explode(',', $_COOKIE['auth']);
//获取id用于向数据库验证
$user_id = $res[1];
//连接数据库
require "config.php";
//查找数据库中的数据
$sql = "SELECT `username`,`password` FROM `tb_member` WHERE `id`=?";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1, $user_id);
$stmt->execute();
//获取查找出的结果集
if($stmt->rowCount() == 1){
//从数据库中获取用户名与密码
$res = $stmt->fetch(PDO::FETCH_ASSOC);
$username = $res['username'];
$password = $res['password'];
//加盐操作
$salt = 'php.cn';
//生成验证令牌
$auth = md5($username.$password.$salt).','.$user_id;
if(($username == $_COOKIE['username']) && ($auth == $_COOKIE['auth'])){//验证通过
if(!empty($_POST['old_account'])){ //用户选择使用旧账号登录
//对用户cookie再延7天
setcookie('username', $username, strtotime("+7 days"));
setcookie('auth', $auth, strtotime("+7 days"));
//登录到首页
exit("<script> location.href = 'index.php'; </script>");
}
else if(!empty($_POST['new_account'])){ //用户选择使用新账号登录
//清空先前用户的cookie
setcookie('username', '', 0);
setcookie('auth', '', 0);
exit("<script> location.href = 'login_new.php'; </script>");
}
}else{//验证不通过
//使用新账号信息登录
//清空先前用户的cookie
setcookie('username', '', 0);
setcookie('auth', '', 0);
exit("<script> location.href = 'login_new.php'; </script>");
}
}
}else{ //本地cookie无用户名与令牌 直接跳转到新账号登录页面
exit("<script>location.href = 'login_new.php';</script>");
}