登录功能实战
一、前端表单页面login.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
<style>
body{
padding:0;
margin: 0;
box-sizing: border-box;
display: flex;
justify-content: center;
background-image: url('apic3595.jpg');
background-size: 100%;
font-size: 30px;
}
.table{
width: 600px;
height: 400px;
background: #fff;
align-self: center;
border-radius: 10px;
box-shadow: 0 0 10px #888;
position: absolute;
top:30%;
padding: 20px;
text-align: center;
}
#username,#password{
width: 100%;
height: 40px;
font-size: 20px;
}
#remember{
width: 20px;
height: 20px;
border: 1px solid red;
}
.td-1{
text-align: start;
}
#submit{
width: 80%;
height: 40px;
font-size: 25px;
border: 0;
}
#submit:hover{
background: #66CC99;
cursor:pointer;
}
</style>
</head>
<body>
<table class="table">
<form action="enter.php" method="POST" onsubmit="return checkForm()">
<tr>
<td>账号:</td>
<td><input type="text" name="username" id="username" placeholder="请输入您的账号" onblur="checkUser()"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" id="password" placeholder="请输入您的密码" onblur="checkPwd()"></td>
</tr>
<tr>
<td><input type="checkbox" name="remember" value="1" id="remember"></td>
<td class="td-1">记住密码</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="登录" id="submit"></td>
</tr>
</form>
</table>
</body>
<script>
function checkUser(){
$username = document.getElementById("username");
if($username.value == ''){
alert('请输入您的账号');
return false;
}else{
return true;
}
}
function checkPwd(){
$password = document.getElementById("password");
if($password.value == ''){
alert('请输入您的密码');
return false;
}else{
return true;
}
}
function checkForm(){
if(checkUser() == true && checkPwd() == true){
return true;
} else{
return false;
}
}
</script>
</html>
<?php
//如果退出的话就清除cookie
if($_GET['action'] == 'out'){
setcookie('username','',time()-3600);
setcookie('auth','',time()-3600);
}else{
$user = $_COOKIE['username'];
//echo $user;
$pwd = $_COOKIE['password'];
if($user != ''){
require "check.php";
//print_r($res);
//如果数据库中查询到了相应数据,就生成令牌
if($stmt->rowCount() == 1){
$username =$res['username'];
$password = $res['password'];
$string = "php.cn";
$auth = md5($username.$password.$string);
//var_dump($auth);
//如果在数据库中查询到的数据生成令牌后和cookie中的令牌不一样
//说明数据库已经被修改过,不能让他登录
if($auth_real == $auth){
exit("
<script>
if(confirm('你已经登录,是否直接登录?')){
location.href='index.php';
}else{
location.href='login.php';
}
</script>
");
}
}
}
}
?>
二、验证提交数据的页面enter.php
<?php
require "config.php";
//设置页面字符集
header("Content-Type:text/html;charset=utf-8");
//获取到表单传过来的账号密码
$username = $_POST['username'];
$password = md5($_POST['password']);
//查看传过来的账号密码
//echo '账号:'.$username.'<br>密码:'.$password.'<br>';
//判断是否有勾选记住密码
$remember = $_POST['remember'];
echo '<br>'.$remember.'<br>';
//连接数据库,把写好的数据库文件直接引入过来
try{
//连接数据库
$pdo = new PDO(DB_DSN,DB_USER,DB_PWD,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING]);
}catch(PDOException $e){
//输出连接错误
echo $e->getMessage();
}catch(Throwable $e){
//输出接口错误
echo $e->getMessage();
}
//要执行的SQL语句
$sql = "SELECT * FROM `user` WHERE `username` = ? AND `password` = ?";
//执行sql语句,因为要返回一个PDOStatemet对象,所以用prepare()
$stmt = $pdo->prepare($sql);
//绑定参数到变量用bindParam()
$stmt->bindParam(1,$username);
$stmt->bindParam(2,$password);
//用ecxute()来执行sql预处理语句
$stmt->execute();
$res = $stmt->fetch(PDO::FETCH_ASSOC);
//查看返回结果
//print_r($res);
//如果返回行数=1的话,代表账号密码输入正确
if($stmt->rowCount() == 1){
//把正确的账号密码存储到cookie中
//先清除上次的cookie
setcookie("username","",time()-3600);
setcookie("auth","",time()-3600);
//如果勾选了记住密码,把账号密码保存7天
if(!empty($remember)){
//用cookie存储账号密码7天
setcookie("username",$username,strtotime("+1 week"));
/*为了密码的安全性,要给密码加密后再放到cookie中存储
盐:在密码学中,是指通过在密码任意固定位置插入特定的字符串,
让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”*/
//加盐
$string = 'php.cn';
//生成令牌
$auth = md5($username.$password.$string).",".$res['id'];
setcookie("auth",$auth,strtotime("+1 week"));
}else{
//没有勾选记住密码
setcookie("username",$username);
//加盐
$string = 'php.cn';
//生成令牌
$auth = md5($username.$password.$string).",".$res['id'];
setcookie("auth",$auth);
}
//存储完cookie后跳转到Index.php
exit("
<script>
location.href='index.php';
</script>
");
}else{
//账号密码输入错误的话,用js弹框并提示用户账号密码输入错误,然后返回登录页面
exit("
<script>
alert('账号或密码输入错误');
location.href='login.php';
</script>
");
}
三、后端首页面index.php
<?php
require "check.php";
if($stmt->rowCount() == 1){
$username =$res['username'];
$password = $res['password'];
$string = "php.cn";
$auth = md5($username.$password.$string);
//var_dump($auth);
//如果在数据库中查询到的数据生成令牌后和cookie中的令牌不一样
//说明数据库已经被修改过,不能让他登录
if($auth_real != $auth){
exit("
<script>
alert('请您先登录');
location.href='login.php';
</script>
");
}
}else{
exit("
<script>
alert('请您先登录');
location.href='login.php';
</script>
");
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>后台首页</title>
<style>
body{
padding: 0px;
margin:0px;
box-sizing: border-box;
}
body > ul{
list-style: none;
display: flex;
width: 100%;
height: 50px;
background:#66CCFF;
}
ul > li{
width: 200px;
height: 50px;
text-align: center;
line-height: 50px;
font-size: 30px;
}
ul>li:hover{
background:#0066FF;
}
ul > li:last-of-type{
margin-left: auto;
margin-right:50px;
}
a{
text-decoration: none;
color:#000;
}
#personal{
width: 150px;
font-size: 25px;
}
li:nth-of-type(4){
width: 400px;
}
ul > li:last-of-type >ul{
padding:0;
margin: 0;
list-style: none;
border: 1px solid #000;
display: flex;
flex-direction: column;
position:absolute;
display: none;
}
ul > li:last-of-type >ul>li{
width: 200px;
height: 50px;
}
ul > li:hover .ul-1{
display: block;
}
</style>
</head>
<body>
<ul>
<li><a href="">首页</a></li>
<li><a href="">购物</a></li>
<li><a href="">学习</a></li>
<li>欢迎<?php echo $_COOKIE['username'] ?>用户回来</li>
<li>
<a href="">个人中心</a>
<ul class="ul-1">
<li><a href="">换肤</a></li>
<li><a href="">设置</a></li>
<li><a href="login.php?action=out">退出</a></li>
</ul>
</li>
</ul>
</body>
</html>
四、cookie与数据库对比公共页面check.php`
- 因为这段代码重复了,所以我直接拿出来放到一个页面,直接引入
<?php
//引入数据库常量
require "config.php";
try{
//连接数据库
$pdo = new PDO(DB_DSN,DB_USER,DB_PWD,[PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING]);
}catch(PDOException $e){
//输出连接错误
echo $e->getMessage();
}catch(Throwable $e){
//输出接口错误
echo $e->getMessage();
}
//
//从cookie中获取auth
$auth = $_COOKIE["auth"];
//把字符串打散为数组
$res = explode(",",$auth);
//var_dump($res);
//拿到数组中的最后一个元素
$id = end($res);
//var_dump($id);
//获取id前面的内容赋值给一个变量
$auth_real = $res[0];
//var_dump($auth_real);
//从数据库中获取
$sql = "SELECT `username`,`password`,`id` FROM `user` WHERE `id` =?";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1,$id);
$stmt->execute();
$res = $stmt->fetch(PDO::FETCH_ASSOC);
五、视频演示
1.不保存密码
2.不保存密码,关掉浏览器,重新打开
3.保存密码,关掉浏览器,再次访问
4.直接访问index.php页面
5.直接访问enter.php页面
6.在勾选密码的情况下修改数据库后直接访问
六、学习总结
1.提交表单数据给enter.php,并验证现在是否是退出操作,是的话清除cookie;不是的话就验证cookie是否存在并且和数据库中的内容一致,一致的话就提示用户账户已登陆是否直接登录;否则就重新登录
2.enter.php验证数据是否和数据库中的数据一致,一样的话,存储到cookie,这里如果勾选了保存密码,就要设置保存时间,没勾选就不设置时间,然后跳到后端首页index.php;如果数据不一致的话,就提示用户账号或密码输入错误,并跳转到登录页面login.php重新登录。
3.当跳转到index.php后,会验证数据库的数据和cookie存储的数据是否一致,不一致说明数据库内容被修改,不能让他登录;一致的话说明没有问题。