博客列表 >20180831 会话机制cookie和session实现用户登陆和验证

20180831 会话机制cookie和session实现用户登陆和验证

乂汁的blog
乂汁的blog原创
2018年09月14日 14:55:101085浏览

一、概述

本节课是一个小的实战练习, 利用cookie和session实现用户登陆和验证,重点除了cookie和session以外还要理解业务逻辑。

二、作业

1、cookie和session优缺点分析

Cookie的优缺点:
优点:极高的扩展性和可用性
通过良好的编程,控制保存在cookie中的session对象的大小。
通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
缺点:
Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
有些状态不可能保存在kh端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在kh端,那么它起不到任何作用。

Session的优缺点:
优点
如果要在诸多Web页间传递一个变量,那么用Session变量要比通过QueryString传递变量可使问题简化。
要使WEb站点具有用户化,可以考虑使用Session变量。你的站点的每位访问者都有用户化的经验,基于此,随着LDAP和诸如MS Site 
Server等的使用,已不必再将所有用户化过程置入Session变量了,而这个用户化是取决于用户喜好的。
你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放。
缺点
Session变量和cookies是同一类型的。如果某用户将浏览器设置为不兼容任何cookie,那么该用户就无法使用这个Session变量!
当一个用户访问某页面时,每个Session变量的运行环境便自动生成,这些Session变量可在用户离开该页面后仍保留20分钟!(事实上,这些变量一直可保留至“timeout”。“timeout”的时间长短由Web服务器管理员设定。一些站点上的变量仅维持了3分钟,一些则为10分钟,还有一些则保留至默认值20分钟。)所以,如果在Session中置入了较大的对象(如ADO 
recordsets,connections, 等等),那就有麻烦了!随着站点访问量的增大,服务器将会因此而无法正常运行!
因为创建Session变量有很大的随意性,可随时调用,不需要开发者做精确地处理,所以,过度使用session变量将会导致代码不可读而且不好维护。
虽然“你可以在任何想要使用的时候直接使用session变量,而不必事先声明它,这种方式接近于在VB中变量的使用。使用完毕后,也不必考虑将其释放,因为它将自动释放”。但是,“谁”想到那儿呢?变量的含义是什么?这些都变得不很清晰。

2、cookie部分

./inc/heade.php

实例

<!--inc文件夹including-->

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<?php
echo isset($page_title) ? $page_title : '<h3>没有标题</h3>';

?>
</body>
</html>

./inc/footer.php

实例

<?php
$page_title = '<hr><h3>这里是底部</h3>';
include 'header.php';

./inc/function.php

实例

<?php
/**
 * 公共函数部分
 */
//当用户登陆成功以后的跳转$page='xxxx.php';
function redirect_user($page = '../index.php'){
    $url = 'http://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
    $url = rtrim($url. '/\\');
    $url .= '/'.$page;
    header('Location:' .$url);
    exit();
}
//验证用户登录
//function check_login($dbc, $email='', $password)
function check_login($dbc, $email='', $password){
    //初始化错误数组
    $errors = [];
    //非空
    if (empty($email)){
        $errors[] = '邮箱不能为空';
        return[false,$errors];
    }else{
        $e = mysqli_real_escape_string($dbc,trim($email));

    }
    if (empty($password)){
        $errors[] = '密码不能为空';
        return[false,$errors];
    }else{
        $p = mysqli_real_escape_string($dbc,trim($password));

    }
    //表中数据验证,$row得到的user_id 和user_name
    if (empty($errors)){
        $sql =  "SELECT `user_id`,`user_name` FROM `user` WHERE `email` = '$e' AND `password` = sha1('$p')";

        //执行
        $res = mysqli_query($dbc,$sql);
        if (mysqli_num_rows($res) == 1){
            $row = mysqli_fetch_array($res,MYSQLI_ASSOC);
            return [true,$row];
        }else{
            $errors[] = '邮箱或者密码不正确';
        }
        return[false,$errors];
    }
}

./inc/connnect.php

实例

<?php
/**
 * 数据库连接,面向过程方法
 * die() 函数输出一条消息,并退出当前脚本。该函数是 exit() 函数的别名。
 */
$dbc = mysqli_connect('127.0.0.1','root','root','php');
if (mysqli_connect_errno()){
    die('连接失败'.mysqli_connect_error());
}
$dbc->set_charset('utf8');

index.php

实例

<?php

include 'inc/header.php';


echo '<h2 style="color:red">首页</h2>';
if (isset($_COOKIE['id'])){

    echo '<p>学号:'.$_COOKIE['id'].'<br>姓名:'.$_COOKIE['name'].'</p><a href="logout.php">退出登陆</a>';
}else{
    echo '<a href = "login.php">游客请登陆</a>';
}

include 'inc/footer.php';

login.php

实例

<?php
/**
 * 对登陆页面(login_page)的数据进行数据验证(通过function里面的方法),
 * 成功后跳转到logged in欢迎页面。
 */
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    require './inc/function.php';
    require './inc/connect.php';

//check_login函数返回两个值,一个布尔值(true/false),一个数组。
    list($check, $data) = check_login($dbc, $_POST['email'], $_POST['password']);
//检测是否通过验证,if(true)
    if ($check == true) {
        setcookie('id', $data['user_id']);
        setcookie('name', $data['user_name']);
        redirect_user('loggedin.php');
    } else $errors = $data;
    mysqli_close($dbc);
}
include 'login_page.php';

loggedin.php

实例

<?php
/*登陆成功界面*/
//判断是否登陆
if (!isset($_COOKIE['id'])){
    require './inc/function.php';
    redirect_user();
}
$page_title = '登陆成功';
include './inc/header.php';
//heredoc??????
echo <<< "WELCOME"
<h2 style = "color:red">登陆成功</h2>
<p>欢迎你{$_COOKIE['name']}</p>
<p><a href="index.php">首页</a> </p>
<p><a href="logout.php">退出</a> </p>
WELCOME;
include './inc/footer.php';

login_page.php

实例

<?php
/**
 * 登陆页面
 */
$page_title = '用户登陆';
include './inc/header.php';
if (isset($errors) && !empty($errors)){
    $errors_msg = '<p style="color: coral">';
    foreach ($errors as $msg){
        $errors_msg .= $msg.'<br>';
    }
    echo $errors_msg.'</p>';
}
?>
<h2 style="color: coral">用户登录</h2>
<form action="login.php" method="post">
    <p>
        <label for="email">邮箱</label>
        <input type="email" name="email" id="email"
               value="<?php echo isset($_POST['email'])?$_POST['email']:'' ?>">
    </p>
    <p>
        <label for="password">密码</label>
        <input type="password" name="password" id="password"
               value="<?php echo isset($_POST['passwor'])?$_POST['password']:'' ?>">
    </p>
    <p>
        <button type="submit" name="submit" id="submit">登陆</button>
    </p>
</form>
<?php include './inc/footer.php';

logout.php

实例

<?php
/**
 * 登出
 */
//判断是否登陆,未登录的话转到function.php使用redirect_user();默认值是index.php再转到登陆界面
if (!isset($_COOKIE['id'])){
    require './inc/function.php';
    redirect_user();
}else{
    setcookie('id','',time()-3600);
    setcookie('name','',time()-3600);

}
$page_title = '退出登陆';
include './inc/header.php';
echo <<< "BYE"
<h2 style="color:red">退出成功</h2>

<p><a href="login.php">登录</a></p>
BYE;
include './inc/footer.php';

结果图:

1.png

2.png

3.png

4.png

5.png

6.png

7.png

2、session部分

(1)启用session在文件开始加入代码:session_start();

(2)session部分的主体代码与cookie的一致。将cookie改为session即可

(3)session的清除与cookie不同:

session_destroy();//清除服务器session
setcookie('PHPSESSID','',time()-3600);

运行区别截图:

session.png

三、总结

1、登陆页面(login_page)数据进行数据验证(通过function里面的方法),成功后跳转到logged in欢迎页面。登出界面判断是否登陆,未登录的话转到function.php使用redirect_user();默认值是index.php再转到登陆界面。

2、check_login函数返回两个值,一个布尔值(true/false),一个数组。

3、$_COOKIE['id']写错为$COOKIE['id']

4、die() 函数输出一条消息,并退出当前脚本。该函数是 exit() 函数的别名。

5、表中数据验证,$row数组中的键名是由sql语句得到的user_id 和user_name,也就是数据库里面的名字。

  


声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议