Cookie与Session
一.认识Cookie与Session
Cookie
1. 为什么要使用Cookie?
web程序是使用HTTP协议传输的,而HTTP协议是无状态的协议,对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2. Cookie什么时候产生?
客户端向服务器端发送一个请求的时,服务端向客户端发送一个Cookie 然后浏览器将Cookie保存
3. Cookie存储位置:
Cookie存储与客户端,我们可以在浏览器中找到它如下:
Session
1. 什么是Session?Session什么时候产生?
Session:称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。简单来说就是在你登录一个网页后可以一段时间内保持登陆状态去浏览。
2. 为什么要使用Session?
因为Cookie保存在客户端,可以伪造,伪造Cookie实现登录进行一些HTTP请求。如果从安全性上来讲,Session比Cookie安全性会高一些。
二.验证过程简单实现
1. Python - flask 实现简单的Session登录:
(1)app.py
# -*- coding: utf-8 -*-
from flask import Flask, render_template, request, redirect, url_for, session, g
from dataclasses import dataclass
app = Flask(__name__,static_url_path="/") # 添加 static_url_path="/" ,文件从当前目录开始
app.config['SECRET_KEY'] = "SAFKSDFASFDSSAFD" # 设置SECRET_KEY,越复杂越好
# 简单来代替数据库,存放临时账户密码
@dataclass
class User:
id: int
username: str
password: str
users = [
User(1,"admin","admin"),
User(2,"test","test"),
User(3,"root","root")
]
@app.before_request
def before_request(): # 在每次访问之前都进行检测,如果检测到没有登录则强制返回登录页
g.user = None
if 'user_id' in session:
user = [u for u in users if u.id == session['user_id']][0]
g.user = user
@app.route("/login", methods = ['GET','POST'])
def login():
if request.method == 'POST': # 登录操作,如果为POST提交,则为登录操作
session.pop('user_id',None)
username = request.form.get("username",None)
password = request.form.get("password",None)
user = [u for u in users if u.username == username ] # 遍历用户名看提交的用户名是否存在
if len(user) > 0:
user = user[0]
if user and user.password == password: # 若存在则查询密码是否正确
session['user_id'] = user.id
return redirect(url_for('proinfo'))
return render_template("login.html")
@app.route("/proinfo")
def proinfo(): # 登录进去后简单展示个人信息
if not g.user:
return redirect(url_for('login'))
return render_template("proinfo.html")
@app.route("/logout")
def logout(): # 清除session,并重定向到登录页
session.pop("user_id",None)
return redirect(url_for('login'))
if __name__ == "__main__":
app.run(debug=True)
(2)登录页面(网上下载的,包含一些css等,在附件中)
<!DOCTYPE html>
<html lang="en">
<head>
<title>测试登录界面</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--===============================================================================================-->
<link rel="icon" type="image/png" href="images/icons/favicon.ico" />
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.7.0/css/font-awesome.min.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="fonts/Linearicons-Free-v1.0.0/icon-font.min.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="vendor/animate/animate.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="vendor/css-hamburgers/hamburgers.min.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="vendor/animsition/css/animsition.min.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="vendor/select2/select2.min.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="vendor/daterangepicker/daterangepicker.css">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="css/util.css">
<link rel="stylesheet" type="text/css" href="css/main.css">
<!--===============================================================================================-->
</head>
<body>
<div class="limiter">
<div class="container-login100">
<div class="wrap-login100">
<div class="login100-form-title" style="background-image: url(images/bg-01.jpg);">
<span class="login100-form-title-1">
欢迎登录--测试
</span>
</div>
<form class="login100-form validate-form" method="post" action="#">
<div class="wrap-input100 validate-input m-b-26" data-validate="用户名必填">
<span class="label-input100">用户名</span>
<input class="input100" type="text" name="username" autocomplete="off">
<span class="focus-input100"></span>
</div>
<div class="wrap-input100 validate-input m-b-18" data-validate="密码必填">
<span class="label-input100">密码</span>
<input class="input100" type="password" name="password" autocomplete="off">
<span class="focus-input100"></span>
</div>
<div class="flex-sb-m w-full p-b-30">
<div class="contact100-form-checkbox">
<input class="input-checkbox100" id="ckb1" type="checkbox" name="remember-me">
<label class="label-checkbox100" for="ckb1">
记住我
</label>
</div>
<div>
<a href="#" class="txt1">
忘记密码?
</a>
</div>
</div>
<div class="container-login100-form-btn">
<button class="login100-form-btn">
登录
</button>
</div>
</form>
</div>
</div>
</div>
<!--===============================================================================================-->
<script src="vendor/jquery/jquery-3.2.1.min.js"></script>
<!--===============================================================================================-->
<script src="vendor/animsition/js/animsition.min.js"></script>
<!--===============================================================================================-->
<script src="vendor/bootstrap/js/popper.js"></script>
<script src="vendor/bootstrap/js/bootstrap.min.js"></script>
<!--===============================================================================================-->
<script src="vendor/select2/select2.min.js"></script>
<!--===============================================================================================-->
<script src="vendor/daterangepicker/moment.min.js"></script>
<script src="vendor/daterangepicker/daterangepicker.js"></script>
<!--===============================================================================================-->
<script src="vendor/countdowntime/countdowntime.js"></script>
<!--===============================================================================================-->
<script src="js/main.js"></script>
</body>
</html>
(3)个人信息展示页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>个人资料</title>
</head>
<body>
<h1>欢迎:{{g.user.username}}</h1>
<p>用户编号 : # {{g.user.id}}</p>
<a href="{{url_for('logout')}}">退出登录</a>
</body>
</html>
2. 测试效果
(1) 打开浏览器访问 http://127.0.0.1:5000/login
(2) 登录admin账户
登录成功,显示admin信息
(3) 新开一个浏览器,直接访问信息展示页面: http://127.0.0.1:5000/proinfo
可以看到,无需登录直接可以看到,我们查看cookie里面有Session字段.说明这里服务端验证Session成功,直接可以访问登录状态请求.
(4) 退出后尝试访问个人信息展示页面
这里我们退出后,Session也被我们的后台清除,此刻再来访问个人信息展示页面:
这里我们访问( http://127.0.0.1:5000/proinfo),被强制重定向到登录页面.说明服务器Session验证失败.