赞
踩
由于HTTP的无状态性,为了使某个域名下的所有网页能够共享某些数据,Cookie和Session应运而生
HTTP是无状态(stateless)协议,一次请求响应结束后,服务器不会留下任何关于对方状态的信息
也就是说,尽管在一个页面登录成功,当跳转到另一个页面时,服务器不会记录当前用户的状态
显然这对于大多数Web程序来说是非常不方便的,为了解决这类问题,就有了Cookie技术
Cookie技术是用来保持web访问状态
Cookie技术通过在请求和响应报文中添加Cookie数据来保存客户端的状态信息
服务器可以设置Cookie的有效期,浏览器会自动清除过期的Cookie
Cookie的作用是让服务器能够认识浏览器,常用于登录模块
Cookie指Web服务器为了存储某些数据(比如用户信息)而保存在浏览器上的小型文本数据
浏览器会在一定时间内保存它,并在下一次向同一个服务器发送请求时附带这些数据
Cookie通常被用来进行用户会话管理
设置Cookie的时候是由我们web服务器设置,也就是在Flask项目中生成Cookie,经由响应报文返回给浏览器保存Cookie,下次浏览器再访问web服务器的时会在请求报文中把Cookie携带过来,所以Cookie产生的起点是在web服务器中,也就是我们的Flask项目中
在Flask中,使用Response类提供的set_cookie()方法可以在响应中添加一个Cookie
其中,set_cookie()方法支持多个参数来设置Cookie的选项
参数 | 说明 |
key | Cookie的键(名称) |
value | Cookie的值 |
max_age | Cookie被保存的时间,单位为秒 默认在用户会话结束(关闭浏览器)时过期 |
expires | 具体的过期时间,一个datetime对象或UNIX时间戳 |
path | 限制Cookie只在给定的路径可用,默认为整个域名下的路径都可用 |
domain | 设置Cookie可用的域名 |
secure | 如果为True,只有通过HTTPS才可以使用 |
httponly | 如果为True,禁止客户端JS获取Cooke |
实例1: 使用Cookie判断用户是否登录
① 创建run.py文件,在文件中创建login()登录页面路由
接收用户提交的表单数据,如果用户名和密码都为"andy123",则表示登录成功。接下来将用户名写入到Cookie
- # run.py
- from flask import Flask, request, render_template, make_response
- app = Flask(__name__)
-
-
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- # 验证表单数据
- if request.method == 'POST':
- # 获取前端提交过来的数据
- username = request.form['username']
- password = request.form['password']
- # 用户名和密码验证
- if username == 'andy123' and password == 'andy123':
- # 如果用户名和密码正确,将用户名写入Cookie
- response = make_response('登录成功!') # 获取response对象
- # set_cookie内的第一个参数是设置cookie的key,第二个参数是用来设置cookie的value
- response.set_cookie('username', username) # 将用户名写入Cookie
- return response # 返回response对象
- return render_template('login.html') # 渲染表单页面
-
-
- if __name__ == '__main__':
- app.run(debug=True)
② 在templates路径下创建login.html,代码如下所示
- <!--login.html-->
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>用户登录</title>
- </head>
- <body>
- <form action="" method="post">
- <div>
- <label for="username">用户名</label>
- <input type="text" id="username" name="username" value="">
- </div>
- <div>
- <label for="password">密 码</label>
- <input type="password" id="password" name="password" value="">
- </div>
- <button type="submit">提交</button>
- </form>
-
- </body>
- </html>
运行run.py文件,在浏览器访问网址:http://127.0.0.1:5000/login,输入用户名"andy123"和密码"andy123",如下图所示
然后单击页面中的【提交】按钮,此时会将用户名写入到Cookie中
③ 在run.py文件中创建index()首页视图函数
判断Cookie值是否存在,如果存在则表示用户已经登录,显示"欢迎来到首页!",否则显示"请先登录!"
查询Cookie是通过请求对象的cookies
属性读取,读取的过程是使用设置Cookie时的key来读取到设置Cookie的value
在run.py文件中添加如下代码
- @app.route('/')
- def index():
- # 判断Cookie是否存在
- if request.cookies.get('username'):
- return '欢迎来到首页!'
- else:
- return '请先登录!'
查看未登录的效果时,需要先清除一下Cookie,在login()视图函数中,并没有设置Cookie的过期时间,则在关闭浏览器时,会自动清除Cookie
所以我们先关闭浏览器,然后再次打开浏览器并访问首页网址: http://127.0.0.1:5000,运行结果如下图所示
接下来访问登录页面网址: htp://127.0.0.1:5000/login,在登录页面输入正确的用户名和密码,此时再次访问首页,运行结果如下图所示
④ 在run.py文件中创建logout()退出登录视图函数
退出登录时,只需要清除Cookie即可。可以调用set_cookie()方法并设置expires参数值为0,则表示Cookie已经过期,在run.py文件中添加如下代码
- @app.route('/logout')
- def logout():
- response = make_response('退出登录!')
- # response.delete_cookie('username')
- # 设置Cookie过期时间为0,即删除Cookie
- response.set_cookie('username', '', expires=0)
- return response
删除Cookie也可以通过Flask内置的Response类实例化出的对象调用delete_cookie('key'),删除的过程是使用设置Cookie时的key来删除Cookie信息
response.delete_cookie('username')
运行run.py文件,在浏览器中访问退出登录的网址: http://127.0.0.1:5000/logout,然后再次访问首页,此时页面显示"请先登录!",表明用户已经退出登录
上述run.py文件完整代码如下所示
- # run.py
- from flask import Flask, request, render_template, make_response
- app = Flask(__name__)
-
-
- @app.route('/')
- def index():
- # 判断Cookie是否存在
- if request.cookies.get('username'):
- return '欢迎来到首页!'
- else:
- return '请先登录!'
-
-
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- # 验证表单数据
- if request.method == 'POST':
- username = request.form['username']
- password = request.form['password']
- if username == 'andy123' and password == 'andy123':
- # 如果用户名和密码正确,将用户名写入Cookie
- response = make_response('登录成功!') # 获取response对象
- # set_cookie内的第一个参数是设置cookie的key,第二个参数是用来设置cookie的value
- response.set_cookie('username', username) # 将用户名写入Cookie
- return response # 返回response对象
- return render_template('login.html') # 渲染表单页面
-
-
- @app.route('/logout')
- def logout():
- response = make_response('退出登录!')
- # response.delete_cookie('username')
- # 设置Cookie过期时间为0,即删除Cookie
- response.set_cookie('username', '', expires=0)
- return response
-
-
- if __name__ == '__main__':
- app.run(debug=True)
前面通过Cookie判断用户是否登录的功能带来一个问题,因为在浏览器中手动添加和修改Cookie是很容易的事情,如果直接把认证信息以明文的方式存储在Cookie里,那么恶意用户就可以通过伪造Cookie的内容来获取对网站的权限,冒用别人的账户
为了避免上述的问题,我们需要对铭感的Cookie内容进行加密,Session的出现就是为了解决Cookie存储数据不安全的问题
Flask提供了Session对象,用来将Cookie数据加密储存
Session指用户会话(user session),即服务器和客户端/浏览器之间或桌面程序和用户之间建立的交互活动
在Flask中,Session对象用来加密Cookie,默认情况下,它会把数据存储在浏览器上一个名为"session"的Cookie里,Session通过密钥对数据进行签名以加密数据。因此我们需要先设置一个密钥,这里的密钥就是一个具有一定复杂度和随机性的字符串
案例2: 使用Session判断用户是否登录
① 创建run.py文件
引入Flask框架,然后设置密钥,具体代码如下所示
- from flask import Flask, request, render_template, session, redirect, url_for
- app = Flask(__name__)
-
- app.secret_key = 'andy12345678' # 设置密钥
然后创建login()登录页面路由,在login()视图函数中判断用户输入的用户名和密码是否正确,如果正确则将"logged_in"写入到session中,具体代码如下所示
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- # 验证表单数据
- if request.method == 'POST':
- username = request.form['username']
- password = request.form['password']
- if username == 'andy123' and password == 'andy123':
- # Session是一个字典对象
- session['logged_in'] = True # 写入session
- return redirect(url_for('index'))
- return render_template('login.html') # 渲染表单页面
创建首页路由,在index视图函数中,使用session.get('logged_in'),即字典取值的方式判断用户是否已经登录,代码如下所示
- @app.route('/')
- def index():
- if session.get('logged_in'):
- return '欢迎来到首页!'
- else:
- return '请先登录!'
最后创建logout()登出页面路由,在logout()视图函数中,使用session.pop('logged_in'),删除该Session值
- @app.route('/logout')
- def logout():
- # 解决用户没有登录就直接退出登录的异常情况
- # 在退出登录前,需要先判断用户是否已经登录,未登录的话直接返回到登录页面即可
- if not session.get('logged_in'):
- return redirect(url_for('login'))
- else:
- session.pop('logged_in')
- return redirect(url_for('login'))
上述run.py文件完整代码如下所示
- from flask import Flask, request, render_template, session, redirect, url_for
- app = Flask(__name__)
-
- app.secret_key = 'andy12345678' # 设置密钥
-
-
- @app.route('/')
- def index():
- if session.get('logged_in'):
- return '欢迎来到首页!'
- else:
- return '请先登录!'
-
-
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- # 验证表单数据
- if request.method == 'POST':
- username = request.form['username']
- password = request.form['password']
- if username == 'andy123' and password == 'andy123':
- session['logged_in'] = True # 写入session
- return redirect(url_for('index'))
- return render_template('login.html') # 渲染表单页面
-
-
- @app.route('/logout')
- def logout():
- # 解决用户没有登录就直接退出登录的异常情况
- # 在退出登录前,需要先判断用户是否已经登录,未登录的话直接返回到登录页面即可
- if not session.get('logged_in'):
- return redirect(url_for('login'))
- else:
- session.pop('logged_in')
- return redirect(url_for('login'))
-
-
- if __name__ == '__main__':
- app.run(debug=True)
② 在templates路径下创建login.html,代码如下所示
- <!--login.html-->
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>用户登录</title>
- </head>
- <body>
- <form action="" method="post">
- <div>
- <label for="username">用户名</label>
- <input type="text" id="username" name="username" value="">
- </div>
- <div>
- <label for="password">密 码</label>
- <input type="password" id="password" name="password" value="">
- </div>
- <button type="submit">提交</button>
- </form>
-
- </body>
- </html>
运行run.py文件,执行效果与案例1一样,读者可自行去演示
其中输入正确的用户名和密码以后,跳转到首页,我们可以查看到Cookie存储了session值
Cookie
Cookie本身由浏览器保存,通过Response将Cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带Cookie过来
Cookie的特点
① 数据全都是存储在客户端中,存储使用的是键值对结构进行存储
② Cookie支持过期时间
③ Cookie不能跨域名,不能跨浏览器
④ 根据域名进行Cookie存储
⑤ Cookie是通过服务器创建的Response来创建的
设置Cookie
- # max_age: 整数,指定Cookie过期时间
- # exprise: 整数,指定过期时间,可以指定一个具体日期时间
- # max_age和exprise两个选一个指定
- response.set_cookie(key, value[, max_age=None, exprise=None])
获取Cookie
request.cookies.get(key)
删除Cookie
response.delete_cookie(key)
Session
Session的特点
① 所有数据存储在服务器中,默认存储在内存中
② 存储结构是键值对(key-value)格式
③ Session依赖于Cookie
设置Session
session['key'] = 'value'
获取Session
session.get(key, default=None)
删除Session
- # 删除某一值
- session.pop(key)
- # 清除所有(慎用,会删除服务器下的所有session)
- session.clear()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。