cookie和session

知识内容:

1.cookie

2.session

3.flask中的cookie和session

4.Django中的cookie和session

 

参考:http://www.cnblogs.com/liwenzhou/p/8343243.html

 

 

 

一、cookie

1.cookie由来

因为http请求是无状态的,每一次请求是独立的(对于服务端来说,一切均如初见!),很难实现保存状态

 

 

2.cookie是什么

Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息

cookie说简单点就是保持在浏览器上的键值对,服务端控制着响应,在响应里可以让浏览器在本地保存这个键值对(cookie),下次请求的时候发送的时候自动携带这个cookie

注意:cookie是服务端设置,但是浏览器(客户端)可以设置cookie(禁用cookie),另外cookie默认关闭浏览器就失效

例如:

1 cookie: _ga=GA1.2.1054004464.1521898033; __gads=ID=e13aa7dde32c5592:T=1526655541:S=ALNI_MZZ6P4iXCRX7EKM9IiKRBTv75Txmw; uaid=2b0dae04996e4d1b9de87d71f6f08088; .CNBlogsCookie=BEA8AC1412C8986DF38732BCAA2D291BAB1AAF7C686923F855A33A923BB8C8F6BE2F84B80CFEC7BBE6A83F23B865AB87D25FED9E10640E1E34269A641C1B0562C85CDD083B46DCC63FC52BF67D409F90936DAD38; .Cnblogs.AspNetCore.Cookies=CfDJ8FHXRRtkJWRFtU30nh_M9mCEXAQL_UyHvUyPS0oSzb3-whvexkm5XnGWepX0a6XLb-6kRfEDb1UgmfX2cmCIy2xLqCn3X8EAAV8GHySMlOc8vyx-_rBZXSgdfdyeUxliaVUUrljH5Y0Y6kO8I4qfemj7rSEWL9COZzWaOwNWlqGYE0Y55r1TUkAZ6W7ZVgsIaeatSFrSEBcsdvF8NdmsWLkPapTH_8qegCV1Sp3beSdaymrdZ4WPiSa1PGGT6jyr-l-Ddt2tKQzrYB_Txu16wSbZqe_xWD1GNATahXlw6AA1qn-sZz9NmkxTuLVvPOaF9Q; _gid=GA1.2.1318394338.1528273714
cookie示例

如何在浏览器上查看cookie(以谷歌浏览器为例):

选择页面右键点开选项选择检查,如下选择即可:

 

cookie从服务器发送到客户端的具体原理:在服务器发送给客户端的响应中如果有一个字段Set-Cookie,浏览器将会保存这个Set-Cookie对应的值,在下次向浏览器请求时带上这个值

 

 

3.cookie应用

问题来了,基于HTTP协议的无状态特征,服务器根本就不知道访问者是“谁”。那么cookie就起到桥接的作用

我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等

具体应用场景如下:

1 登录、七天免登录
2 记录用户的浏览习惯
3 简单的投票限制

 

 

 

二、session

1.session的由来

cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session

 

 

2.session是什么

session:保存在服务端的键值对

session必须依赖cookie,如下所示:

 

 

3. cookie和session比较

cookie:存储数据小、安全性差

session:存储数据大、安全性好

总结而言:cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本

另外,上述所说的cookie和cookie其实是共通性的东西,不限于语言和框架。

 

 

 

三、flask中的cookie和session

(1)flask的cookie

1 # flask写入 cookie, 必须使用 make_response 函数
2 # 然后再用 set_cookie 来设置 cookie
3 r = make_response(template)
4 r.set_cookie('cookie_name', 'wyb')
5 return r

 

(2)flask的session

flask中有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥:

  • 设置:session['username'] = 'xxx'
  • 取出session值:session.get('username', None)
  • 删除:session.pop('username', None)

基本使用(没有登录就让其登录,登录了页面显示登录成功,点击logout注销回到登录页面):

 1 from flask import Flask, session, redirect, url_for, escape, request
 2 
 3 app = Flask(__name__)
 4 # set the secret key.  keep this really secret:
 5 app.secret_key = 'abcdefghyjklmnopqrstasdfu280975298165=-'
 6 
 7 # escape(session['username']), session.get("username", None)是两种取session中值的方法
 8 @app.route('/')
 9 def index():
10     if 'username' in session:
11         return 'Logged in as %s(%s), %s' % (escape(session['username']), session.get("username", None), "<a href='/logout'>注销</a>")
12     return redirect(url_for("login"))
13 
14 @app.route('/login', methods=['GET', 'POST'])
15 def login():
16     if request.method == 'POST':
17         session['username'] = request.form['username']
18         return redirect(url_for('index'))
19     return '''
20         <form action="" method="post">
21             <p><input type=text name=username>
22             <p><input type=submit value=Login>
23         </form>
24     '''
25 
26 @app.route('/logout')
27 def logout():
28     # remove the username from the session if it's there
29     session.pop('username', None)
30     return redirect(url_for('login'))
31 
32 if __name__ == '__main__':
33     app.run(debug=True)

 

 

 

四、Django中的cookie和session

(1) django中的cookie

 1 # Cookie: 保存在浏览器端的键值对
 2  
 3 # 为什么要有Cookie: 因为HTTP请求是无状态的
 4   
 5 # Cookie的原理:
 6 """
 7 服务端可以在返回响应的时候 做手脚
 8 在浏览器上写入键值对(Cookie)
 9      
10 浏览器发送请求的时候会自动携带该网站保存在我浏览器的键值对(Cookie)
11 """
12      
13 # Django 从请求携带的Cookie中取值:
14     request.COOKIES.get("is_login")
15     request.get_signed_cookie(key, default=None, salt="xxx")
16 # Django中设置Cookie:(针对的是响应对象)
17     rep = HttpResponse()/render(request, "test.html)/redirect()
18     rep.set_cookie(key, value)
19     # rep.set_signed_cookie(key, value, salt="xxx", max_age=7)
20 # Django中删除Cookie:(注销)
21     rep.delete_cookie(key)

删除cookie实现注销:

1 def logout(request):
2     rep = redirect("/login/")
3     rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
4     return rep

cookie实现登陆验证: 

 1 def check_login(func):
 2     @wraps(func)
 3     def inner(request, *args, **kwargs):
 4         next_url = request.get_full_path()
 5         if request.get_signed_cookie("login", salt="SSS", default=None) == "yes":
 6             # 已经登录的用户...
 7             return func(request, *args, **kwargs)
 8         else:
 9             # 没有登录的用户,跳转刚到登录页面
10             return redirect("/login/?next={}".format(next_url))
11     return inner
12 
13 
14 def login(request):
15     if request.method == "POST":
16         username = request.POST.get("username")
17         passwd = request.POST.get("password")
18         if username == "xxx" and passwd == "xxx":
19             next_url = request.GET.get("next")
20             if next_url and next_url != "/logout/":
21                 response = redirect(next_url)
22             else:
23                 response = redirect("/index/")
24             response.set_signed_cookie("login", "yes", salt="xxx")
25             return response
26     return render(request, "login.html")

 

(2)django中的session

 1 # Session保存在服务端的键值对,另外Session依赖于Cookie
 2 
 3 """
 4 Session原理:
 5     用户数据:
 6     xasdfvxs: {"is_login": 1, "name": "xiaohei", "age":18}
 7     safsdfsdf: {"is_login": 1, "name": "xiaobai", "age":20}
 8     wergasfd: {"is_login": 0, "name": "xiaohui", "age":48}
 9 
10     给浏览器写入Cookie:
11         sessionid: wergasfd
12     
13     1. 从用户发来的请求的Cookie中 根据 sessionid 取值, 取到一个随机字符串
14     2. 根据这个随机字符串找到对应的 Session 数据  --> {"is_login": 0, "name": "xiaohui", "age":48}
15     3. request.session.get("is_login")    --> 从Session取值
16 """
17 
18 
19 # Django中设置Session:
20     request.session["is_login"] = 1
21 
22 # Django设置session和cookie的超时时间 (Cookie和Session数据的)
23     request.session.set_expiry(7)  
24     # 如果value是个整数,session会在些秒数后失效。
25     # 如果value是个datatime或timedelta,session就会在这个时间后失效。
26     # 如果value是0,用户关闭浏览器session就会失效。
27     # 如果value是None,session会依赖全局session失效策略。
28 
29 # Django中取出session中的值
30     request.session.get("is_login")
31 
32 # 在settings.py中设置,每次请求都刷新Session超时时间
33     SESSION_SAVE_EVERY_REQUEST = True 
34 
35 # Django中删除Session:
36     request.session.delete()   # 只删除session
37     request.session.flush()     # 清除Cookie和Session数据
38     request.session.clear_expired()  将所有Session失效日期小于当前日期的数据删除

 

(3)django中的session配置

 1 1. 数据库Session
 2 SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
 3 
 4 2. 缓存Session
 5 SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
 6 SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
 7 
 8 3. 文件Session
 9 SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
10 SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
11 
12 4. 缓存+数据库
13 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
14 
15 5. 加密Cookie Session
16 SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
17 
18 其他公用设置项:
19 SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
20 SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
21 SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
22 SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
23 SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
24 SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
25 SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
26 SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
27 
28 Django中Session相关设置

 

(4)Django中CBV使用装饰器实现登陆验证

要在CBV视图中使用我们上面的check_login装饰器,需要使用以下的django内置的方法:

1 from django.utils.decorators import method_decorator

当然关于这个方法的使用有以下三种方式:

1. 加在CBV视图的get或post方法上:

 1 from django.utils.decorators import method_decorator
 2 
 3 class HomeView(View):
 4     def dispatch(self, request, *args, **kwargs):
 5         return super(HomeView, self).dispatch(request, *args, **kwargs)
 6 
 7     def get(self, request):
 8         return render(request, "home.html")
 9     
10     @method_decorator(check_login)
11     def post(self, request):
12         print("Home View POST method...")
13         return redirect("/index/")

2. 加在dispatch方法上:

 1 from django.utils.decorators import method_decorator
 2 
 3 class HomeView(View):
 4     @method_decorator(check_login)
 5     def dispatch(self, request, *args, **kwargs):
 6         return super(HomeView, self).dispatch(request, *args, **kwargs)
 7 
 8     def get(self, request):
 9         return render(request, "home.html")
10 
11     def post(self, request):
12         print("Home View POST method...")
13         return redirect("/index/")
14 
15 # 因为CBV中首先执行的就是dispatch方法,所以这么写相当于给get和post方法都加上了登录校验

3. 直接加在视图类上:

 1 # 如果get方法和post方法都需要登录校验的话就写两个装饰器
 2 # 注意method_decorator必须传name关键字参数
 3 
 4 from django.utils.decorators import method_decorator
 5 
 6 @method_decorator(check_login, name="get")
 7 @method_decorator(check_login, name="post")
 8 class HomeView(View):
 9     def dispatch(self, request, *args, **kwargs):
10         return super(HomeView, self).dispatch(request, *args, **kwargs)
11 
12     def get(self, request):
13         return render(request, "home.html")
14 
15     def post(self, request):
16         print("Home View POST method...")
17         return redirect("/index/")

 

posted @ 2018-06-07 18:29  woz333333  阅读(233)  评论(0编辑  收藏  举报