用cookie和session分别实现登录与注册验证
-作业的显示页面为三个,一个是主页有登录和注册入口,一个是登录页面,一个是注册页面。除了显示的三个页面外,还需要一个控制分发的脚本。
-从流程图中可以看见:
未登录主页有两个出口一个是登录,一个是注册;
已登录主页有一个出口就是退出;
登录有两个出口一个是登录主页,一个是转向注册页;
注册有两个出口一个是注册主页,一个是转向登录页;
其中除了登录与注册页之间的相互跳转外,其余均应通过控制分发脚本进行处理并分发。
-登录页、注册页和主页退出均是通过$_GET
来传递参数供控制分发脚本进行判断。
-登录页、注册页表单中的数据均是通过$_POST
来向控制分发脚本传递参数的。
-控制分发脚本处理完的参数在cookie方法中,是通过将数据序列化后存入$_COOKIE
这个超全局变量中供主页调用的。
$users = [
['id' => 1,'email' => 'admin@php.cn','name' => 'admin','password' => '8843028fefce50a6de50acdf064ded27'],
['id' => 2,'email' => 'peter@qq.cn','name' => 'peter','password' => '5ba1a3fc5fa1363689baab6b3288def8'],
['id' => 3,'email' => 'dseven@php.cn','name' => 'dseven','password' => '84d28f2183a9f2cf67b8b08f7652f757'],
];
以上代码是建立一个二维数组,用来模拟数据表,可以实验用户登录验证的数据,其中password
字段是经过加密函数加密后的字符串。
$allowNames = ['index.php','log.php','reg.php'];
$currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
if(!in_array($currentName,$allowNames)){
exit('非法来源');
}
以上代码是建立一个脚本白名单,并进行来源验证,主要是防止用户直接进入控制分发页,从流程图中可以看见能进入控制分发页的只有主页、登录页和注册页,将其三个放入一个数组中形成白名单,然后用请求页的$_SERVER['HTTP_REFERER']
的值来进行判断。其中basename()
的作用是将路径去掉,只保留脚本名。
$action = filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
$action = strtolower($action);
以上代码是分析整理用户通过$_GET
传过来的参数,以供下部进行分发判断。
case 'log':
if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST'){
$email = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL);
$email = filter_var($email,FILTER_SANITIZE_EMAIL);
$password = md5(sha1(filter_input(INPUT_POST,'password'))) ;
$results = array_filter($users,function ($user)use($email,$password){
return $email === $user['email']&&$password === $user['password'];
});
if(count($results) === 1){
setcookie('user',serialize(array_pop($results)));
exit('<script>alert("验证通过");location.href="index.php";</script>');
}else{
exit('<script>alert("验证未通过,请重新登录或注册");location.href="log.php";</script>');
}
}
break;
以上代码是switch($action)
中的一个分支,主要是用来分析处理登录页面的数据。其基本步骤是:首先分析登录页面提交的数据是否通过POST
方法传递,其次依次处理email
和password
的值,然后通过array_filter()
和最开始建立的二维数组中的数据进行比对,第四步是将比对成功的数组的值序列化,并通过setcookie()
写入COOKIE中,供主页调用。
case 'reg':
$email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
$password = md5(sha1(filter_input(INPUT_POST,'password1'))) ;
$name = filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$id = 4;
$data = compact('id','email','name','password');
$i = count($users);
if(array_push($users,$data) === $i+1){
setcookie('user',serialize(array_pop($users)));
exit('<script>alert("注册成功");location.href="index.php";</script>');
}
break;
以上代码是switch($action)
中的一个分支,主要是用来分析处理注册页面的数据。其基本步骤是:首先用三个变量分别获取注册页面传来的三个值;其次是将三个值与ID值一起通过compact()
组合成一个数组,将组合成的数组通过array_push()
压入用户表信息二维数组中(注意此处只是演示,只能暂时压入,不会永久保留);第三步是将之前组合成的数组取值并进行序列化,然后通过setcookie()
写入COOKIE中,供主页调用。此处需要注意的是:array_push()
返回的是数组入栈后的总数量,而不是布尔值,因此不能用恒等于1来判断是否入栈成功,而要用整体数量是否加1来判断。
case 'logout':
if(filter_input(INPUT_COOKIE,'user')){
setcookie('user',null,time()-3600);
exit('<script>alert("退出成功");location.href="index.php";</script>');
}
break;
以上代码,是用来处理主页退出登录的请求。关键点在于用setcookie()
来注销掉之前建立的$_COOKIE[user]
,基本原理就是给它赋一个空值,并给一个过期时间,实际上只给过期时间也可以。
<?php
if(filter_has_var(INPUT_COOKIE,'user')){
$user = unserialize(filter_input(INPUT_COOKIE,'user'));
}
?>
以上代码主要是用来,获取从控制分发页送至COOKIE的值。需要注意的是,在取值时要进行反序列化。
<span>
<?php if(isset($user)) :?>
<a href="">
<?php echo $user['name'];?> </a>
<a href="" id="logout">退出</a>
<?php else : ?>
<a href="log.php">登录</a>
<span>¦</span>
<a href="reg.php">注册</a>
<?php endif ?>
</span>
以上代码主要实现的是不同状态下主页显示不同的链接和信息。
-根据自己的理解其实过滤器应该是分为过滤函数和过滤器两类。其中filter_var()
是属于过滤函数,FILTER_SANITIZE_EMAIL
是属于过滤器也就是一种过滤规则,是过滤函数的一个参数。
个人感觉filter_var()
如果加上合适的过滤器的话和filter_input()
的效果基本一致,不过filter_var()
不能直接从脚本外部获取输入并过滤,需要先建立一个变量并赋值之后才行。
-感觉cookie就是浏览器中设立的一个容器,其他脚本都可以通过setcookie()
来给里面装上东西,而且这个装好的东西不会随着安装脚本的消失而消失,它会一直保留在浏览器的容器中,这样别的脚本就能从中调用,达到不同脚本之间传递消息的功能。
-SESSION感觉像是比COOKIE更保密的容器,基本效果和作用都一样,不过用之前需要建立会话,用的过程中不需要过滤。
<?php
if(filter_has_var(INPUT_COOKIE,'user')){
$user = unserialize(filter_input(INPUT_COOKIE,'user'));
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页面</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="header">
<div class="box">
<a href="">首页</a>
<span>
<?php if(isset($user)) :?>
<a href=""><?php echo $user['name'];?></a>
<a href="" id="logout">退出</a>
<?php else : ?>
<a href="log.php">登录</a>
<span>¦</span>
<a href="reg.php">注册</a>
<?php endif ?>
</span>
</div>
</div>
<script>
document.querySelector('#logout').addEventListener('click',function (event) {
if(confirm('是否退出')){
event.preventDefault();
window.location.assign('handle.php?action=logout');
}
});
</script>
</body>
</html>
<?php
$users = [
['id' => 1,'email' => 'admin@php.cn','name' => 'admin','password' => '8843028fefce50a6de50acdf064ded27'],
['id' => 2,'email' => 'peter@qq.cn','name' => 'peter','password' => '5ba1a3fc5fa1363689baab6b3288def8'],
['id' => 3,'email' => 'dseven@php.cn','name' => 'dseven','password' => '84d28f2183a9f2cf67b8b08f7652f757'],
];
//获取脚本名
$allowNames = ['index.php','log.php','reg.php'];
$currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
if(!in_array($currentName,$allowNames)){
exit('非法来源');
}
//请求的分发处理
$action = filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
$action = strtolower($action);
switch ($action){
case 'log':
if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST')
{
$email = filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL);
$email = filter_var($email,FILTER_SANITIZE_EMAIL);
$password = md5(sha1(filter_input(INPUT_POST,'password'))) ;
$results = array_filter($users,function ($user)use($email,$password){
return $email === $user['email']&&$password === $user['password'];
});
if(count($results) === 1){
setcookie('user',serialize(array_pop($results)));
exit('<script>alert("验证通过");location.href="index.php";</script>');
}else{
exit('<script>alert("验证未通过,请重新登录或注册");location.href="log.php";</script>');
}
}
break;
case 'reg':
$email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
$password = md5(sha1(filter_input(INPUT_POST,'password1'))) ;
$name = filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$id = 4;
$data = compact('id','email','name','password');
$i = count($users);
if(array_push($users,$data) === $i+1){
setcookie('user',serialize(array_pop($users)));
exit('<script>alert("注册成功");location.href="index.php";</script>');
}
break;
case 'logout':
if(filter_input(INPUT_COOKIE,'user')){
setcookie('user',null,time()-3600);
exit('<script>alert("退出成功");location.href="index.php";</script>');
}
break;
default:
echo '未定义操作';
}
<?php
if(filter_has_var(INPUT_COOKIE,'user')){
exit('<script>alert("请不要重复登录");location.href="index.php";</script>');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
<link rel="stylesheet" href="css/log.css">
</head>
<body>
<h2>用户登录</h2>
<div class="container">
<form action="handle.php?action=log" method="post" id="log" name="log">
<span>
<label for="email">邮箱:</label>
<input type="email" name="email" id="email" placeholder="请输入邮箱地址" >
</span>
<span>
<label for="password">密码:</label>
<input type="password" name="password" id="password" placeholder="请输入密码" >
</span>
<span>
<button type="submit">登录</button>
</span>
</form>
</div>
<a href="reg.php">没有注册,去注册吧</a>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
<link rel="stylesheet" href="css/reg.css">
</head>
<body>
<h2>用户注册</h2>
<div class="container">
<form action="handle.php?action=reg" method="post" id="reg" name="reg">
<span>
<label for="email">邮箱:</label>
<input type="email" name="email" id="email" placeholder="请输入邮箱地址" >
<label for="email"></label>
</span>
<span>
<label for="username">昵称:</label>
<input type="text" name="username" id="username" placeholder="请输入用户名"
autocomplete="off" form="reg" required autofocus>
<label for="username">不超过20个字符</label>
</span>
<span>
<label for="password">密码:</label>
<input type="password" name="password" id="password" placeholder="请输入密码" form="reg" required autofocus>
<label for="password">不少于8位</label>
</span>
<span>
<label for="password1">重复密码:</label>
<input type="password1" name="password1" id="password1" placeholder="请重复密码" required autofocus>
<label for="password1">两次密码必须一致</label>
</span>
<span>
<button type="submit">提交注册</button>
<button type="reset">重新填写</button>
</span>
</form>
</div>
<a href="log.php">已经注册了,返回登录</a>
</body>
</html>
<?php
session_start();
if(isset($_SESSION['user'])){
$user = $_SESSION['user'];
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主页面</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="header">
<div class="box">
<a href="">首页</a>
<span>
<?php if(isset($user)) :?>
<a href=""><?php echo $user['name'];?></a>
<a href="" id="logout">退出</a>
<?php else : ?>
<a href="log.php">登录</a>
<span>¦</span>
<a href="reg.php">注册</a>
<?php endif ?>
</span>
</div>
</div>
<script>
document.querySelector('#logout').addEventListener('click',function (event) {
if(confirm('是否退出')){
event.preventDefault();
window.location.assign('handle.php?action=logout');
}
});
</script>
</body>
</html>
<?php
session_start();
if(isset($_SESSION['user'])){
exit('<script>alert("请不要重复登录");location.href="index.php";</script>');
}
//?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
<link rel="stylesheet" href="css/log.css">
</head>
<body>
<h2>用户登录</h2>
<div class="container">
<form action="handle.php?action=log" method="post" id="log" name="log">
<span>
<label for="email">邮箱:</label>
<input type="email" name="email" id="email" placeholder="请输入邮箱地址" >
</span>
<span>
<label for="password">密码:</label>
<input type="password" name="password" id="password" placeholder="请输入密码" >
</span>
<span>
<button type="submit">登录</button>
</span>
</form>
</div>
<a href="reg.php">没有注册,去注册吧</a>
</body>
</html>
<?php
session_start();
$users = [
['id' => 1,'email' => 'admin@php.cn','name' => 'admin','password' => '8843028fefce50a6de50acdf064ded27'],
['id' => 2,'email' => 'peter@qq.cn','name' => 'peter','password' => '5ba1a3fc5fa1363689baab6b3288def8'],
['id' => 3,'email' => 'dseven@php.cn','name' => 'dseven','password' => '84d28f2183a9f2cf67b8b08f7652f757'],
];
//设置合法请求的白名单
$allowNames = ['index.php','log.php','reg.php'];
//获取脚本名
$currentName = basename(filter_input(INPUT_SERVER,'HTTP_REFERER'));//变量中只有键名
if(!in_array($currentName,$allowNames)){
exit('非法来源');
}
//请求的分发处理
$action = filter_input(INPUT_GET,'action',FILTER_SANITIZE_STRING);
$action = strtolower($action);
switch ($action){
case 'log':
if(filter_input(INPUT_SERVER,'REQUEST_METHOD') === 'POST'){
$email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
$password = md5(sha1(filter_input(INPUT_POST,'password'))) ;
$results = array_filter($users,function ($user)use($email,$password){
return $email === $user['email']&&$password === $user['password'];
});
if(count($results) === 1){
$_SESSION['user'] = array_pop($results) ;
exit('<script>alert("验证通过");location.href="index.php";</script>');
}else{
exit('<script>alert("验证未通过,请重新登录或注册");location.href="log.php";</script>');
}
}
break;
case 'reg':
$email = filter_var(filter_input(INPUT_POST,'email',FILTER_VALIDATE_EMAIL),FILTER_SANITIZE_EMAIL);
$password = md5(sha1(filter_input(INPUT_POST,'password1'))) ;
$name = filter_input(INPUT_POST,'username',FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$id = 4;
$data = compact('id','email','name','password');
$i = count($users);
if(array_push($users,$data) === $i+1){
$_SESSION['user'] = array_pop($users) ;
exit('<script>alert("注册成功");location.href="index.php";</script>');
}
break;
case 'logout':
if(isset($_SESSION['user'])){
session_destroy();
exit('<script>alert("退出成功");location.href="index.php";</script>');
}
break;
default:
echo '未定义操作';
}
Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号