session在Flask中一般用作设置某些页面的权限,好比某些页面必需要登陆才能够看到,登陆的信息或标志就放到session中.它的使用过程以下:html
# encoding: utf-8 from flask import Flask from flask import request, session, redirect from functools import wraps app = Flask(__name__) app.config['SECRET_KEY'] = 'you never guess' # 使用 session 必需要配置这个,加密签名. # 登陆、注册认证函数 def authorize(fn): @wraps(fn) def wrapper(*args, **kwargs): # 这里就像过滤器,有了那个修饰器标志的视图函数都必须通过这个函数才能够返回请求 user = session.get('logged_in', None) # 取得登陆标志 if user: return fn(*args, **kwargs) # 登陆了就返回请求 else: return 'need login!' # 不然就转到注册的页面 return wrapper @app.route('/') @app.route('/home') def index(): session["global_name"] = "global_path" return session["global_name"] + 'home.html' @app.route('/find') def find(): print(vars(session)) return session.get("global_name", "None") + 'find.html' @app.route('/doc') @authorize # 这个修饰器表示,这个视图页面必须登陆才能够访问 def blog(): print(session['username']) return 'blog.html' # 登陆用户 @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'GET': return "login.html" if request.method == 'POST': username = request.values.get('username') password = request.values.get('password') if username and password: session['logged_in'] = True # 登陆成功 session['username'] = username session['password'] = password return username + password else: return "need username and password" # 注销用户 @app.route('/signout', methods=['GET', 'POST']) @authorize def logout(): session['logged_in'] = False # 变成false 就意味着须要从新登陆了 return redirect('/home') if __name__ == '__main__': app.run()
# 登陆接口与返回,能够看出response中set-cookie了 curl -X POST "http://127.0.0.1:5000/login" -d "username=test&password=123" HTTP/1.0 200 OK Set-Cookie: session=eyJsb2dnZWRfaW4iOnRydWUsInBhc3N3b3JkIjoiMTIzIiwidXNlcm5hbWUiOiJsZ2oifQ.DoNGjg.4c2Adke_tzqo5MW_BHs95FvY6i4; HttpOnly; Path=/ # 不带cookie访问须要登陆的接口 curl "http://127.0.0.1:5000/doc" need signin! # 带上cookie后访问经过 curl --cookie "session=eyJsb2dnZWRfaW4iOnRydWUsInBhc3N3b3JkIjoiMTIzIiwidXNlcm5hbWUiOiJsZ2oifQ.DoNGjg.4c2Adke_tzqo5MW_BHs95FvY6i4" "http://127.0.0.1:5000/doc" user/blog.html # 登出接口也是同上的. curl "http://127.0.0.1:5000/logout" need signin! curl --cookie "session=eyJsb2dnZWRfaW4iOnRydWUsInBhc3N3b3JkIjoiMTIzIiwidXNlcm5hbWUiOiJsZ2oifQ.DoNGjg.4c2Adke_tzqo5MW_BHs95FvY6i4" "http://127.0.0.1:5000/signout" <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>Redirecting...</title> <h1>Redirecting...</h1> <p>You should be redirected automatically to target URL: <a href="/home">/home</a>. If not click the link. # 使用session存储一些其余信息也是依赖于cookie存在的 curl -v "http://127.0.0.1:5000" global_pathhome.html HTTP/1.0 200 OK Set-Cookie: session=eyJnbG9iYWxfbmFtZSI6eyIgYiI6IloyeHZZbUZzWDNCaGRHZz0ifX0.DoNPag.ooEMHsinZlKRQpLF_-S3axsH3jc; HttpOnly; Path=/ # 想要获得设置global_name,不带cookie是得不到的 curl "http://127.0.0.1:5000/find" Nonefind.html # 带cookie curl --cookie "session=eyJnbG9iYWxfbmFtZSI6eyIgYiI6IloyeHZZbUZzWDNCaGRHZz0ifX0.DoNPag.ooEMHsinZlKRQpLF_-S3axsH3jc" "http://127.0.0.1:5000/find" global_pathfind.html # 设置cookie curl -v "http://127.0.0.1:5000/set_cookie" < HTTP/1.0 200 OK < Set-Cookie: name=test; Expires=Wed, 19-Sep-2018 03:42:31 GMT; Max-Age=200; Path=/ < Set-Cookie: age=18; Path=/ set_cookie* Closing connection 0 # 获取cookie curl --cookie "name=test;age=18" "http://127.0.0.1:5000/get_cookie" name is test,name is 18
平时使用浏览器访问接口,很难注意到cookie和session的区别与联系,使用curl就把区别暴露了出来.
上面的curl交互能够看出 session是会以set-cookie的方式设置到浏览器中,以后的访问都会将cookie带上请求其余接口,若使用curl而不带上cookie就会致使错误,这也是为何说session是依赖cookie存在的.python
cookie存在的目的:chrome
由于http协议属于无状态协议,它不跟踪从一个客户端到另外一个客户端的请求信息.也就是说即便第一次和服务器链接后而且登陆成功,第二次请求服务器依然不知道请求的是哪一个用户.
因此使用cookie来解决这个问题:第一次登陆成功后,服务器返回cookie给浏览器,而后浏览器保存在本地,当用户发送第二次请求时,就会自动的把上次请求存储的cookie数据携带给服务器,服务器再根据cookie数据判断是哪一个用户.shell
session和cookie的做用相似:
也是用来存储用户相关的信息,存储在服务器端.把用户的信息通过加密后存储在session中,而后产生一个惟一的session_id.flask
cookie和session的结合使用数组
通常有两种存储方式:浏览器
(1) 存储在服务器端:经过cookie存储一个session_id,而后具体的数据则是保存在session中.若是用户已经登陆,则服务器会在cookie中保存一个session_id,下次再请求时,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据,就知道用户究竟是谁了.以及以前保存的一些状态信息,这种专业术语叫作server side session. (2) 存储在客户端:将session数据加密,而后存储在cookie中.这种专业术语叫作 client side session.flask框架采用的就是这种方式,可是能够替换成其余形式.
把用户信息通过加密后放入到session中,而后把session存放到cookie中.下次请求时,从浏览器发送过来的cookie中读取到session,而后再从session中读取数据并解密,获取最终的用户数据.这样能够节省服务器开销.缓存
1) 能够经过在浏览器中设置来清除cookie. (2) 使用Response的set_cookie进行清除 @app.route('/del_cookie') def del_cookie(): response=make_response('delete cookie') response.set_cookie('Name','',expires=0) return response (3)使用Response的 delete_cookie方法. @app.route('/del_cookie2') def del_cookie2(): response=make_response('delete cookie2') response.delete_cookie('Name') return response
观察"Set-Cookie: name=test; Expires=Wed, 19-Sep-2018 03:42:31 GMT; Max-Age=200; Path=/" 能够看出其实cookie有不少属性,以下:安全
在chrome控制台中的resources选项卡中能够看到cookie的信息。 一个域名下面可能存在着不少个cookie对象。 name 字段为一个cookie的名称。 value 字段为一个cookie的值。 domain 字段为能够访问此cookie的域名。 非顶级域名,如二级域名或者三级域名,设置的cookie的domain只能为顶级域名或者二级域名或者三级域名自己,不能设置其余二级域名的cookie,不然cookie没法生成。 顶级域名只能设置domain为顶级域名,不能设置为二级域名或者三级域名,不然cookie没法生成。 二级域名能读取设置了domain为顶级域名或者自身的cookie,不能读取其余二级域名domain的cookie。因此要想cookie在多个二级域名中共享,须要设置domain为顶级域名,这样就能够在全部二级域名里面或者到这个cookie的值了。 顶级域名只能获取到domain设置为顶级域名的cookie,其余domain设置为二级域名的没法获取。 path 字段为能够访问此cookie的页面路径。 好比domain是abc.com,path是/test,那么只有/test路径下的页面能够读取此cookie。 expires/Max-Age 字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一块儿失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。 Size 字段 此cookie大小。 http 字段 cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能经过document.cookie来访问此cookie。 secure 字段 设置是否只能经过https来传递此条cookie
下面是flask中cookie对应属性的配置项服务器
SECRET_KEY 密钥 SESSION_COOKIE_NAME 会话 cookie 的名称 SESSION_COOKIE_DOMAIN 会话 cookie 的域。若是没有设置的话, cookie 将会对 SERVER_NAME 全部的子域都有效。 SESSION_COOKIE_PATH 会话 cookie 的路径。若是没有设置或者没有为 '/' 设置,cookie 将会对全部的 APPLICATION_ROOT 有效。 SESSION_COOKIE_HTTPONLY 控制 cookie 是否应被设置 httponly 的标志, 默认为 True 。 SESSION_COOKIE_SECURE 控制 cookie 是否应被设置安全标志,默认为 False。
既然session依赖cookie,要是浏览器禁用了cookie改怎么达到状态保持的效果呢?
这个时候,就须要用到URL重写了,既让服务器收到的每一个请求参数中都带有sessioinId,也就是从本来的隐式(headers传参)变为url或body传参。
当咱们清空浏览器的时候,session会消失吗?
这个问题包含着一些陷阱。由于不少时候当咱们清空浏览器之后,确实须要从新登陆系统才能够操做,因此不少人天然而然认为清空浏览器缓存(包含cookie)之后session就会消失。
其实这种结论是错误的。要知道,session是存在于服务器的,你清除浏览器缓存,只是清除了cookie,跟session一点关系都没有。那么为何咱们却不能访问网站,而须要从新登陆了呢?由于清空了浏览器缓存,这时候cookie数组中一定不会有JSESSIONID这个cookie,因此必须得新建一个session,用新的sessionId来给JSESSIONID这个cookie赋值。因为是新建的session,session中一定没有userId这样的属性值,因此判断结果天然为空,因此须要从新登陆。此次赋值之后,下一次再请求该网站的时候,因为cookie数组中已经有了JSESSIONID这个cookie,而且能经过该JSESSIONID的值找到相应的session,因此就不须要再从新登陆了。