1.cookie的原理

客户端登陆到服务器后,服务器会创建一个cookie,里面记载着登陆的用户名,密码等信息,传给客户端保存到本地,客户端下次和服务器的通信,就会携带着这个记录了用户名和密码信息的cookie,去访问服务器,服务器就会识别到是哪个用户访问.
2.session的原理

采用了session会话机制后,用户登陆到服务器后,服务器会创建一个表,记录着用户的sessionid(会话id)和用户名的关系.同时创建带有这个sessionid的cookie返回给客户端.客户端下次通信的时候,只需要携带这个sessionid的cookie访问,服务器根据sessionid找到对应表中的会话id是否存在,来识别时哪个用户访问.如果表中不存在,则说明用户没有登录,或者登录已过期,需要重新登陆.
HttpRequest对象的request.session
HttpResponse对象的set_cookie
,delete_cookie
1.request.session:返回一个QueryDict的类字典类型的集合,这个属性要有效,必须添加SessionMiddleware这个中间件。
2.set_cookie(key,value=’’,max_age=None,expires=None,path=’/’,domain=None,secure=None,httponly=False)
设置cookie的方法。
key:cookie的key。
value:cookie的value。
max_age:cookie最大的过期时间。
expires:cookie的过期时间和日期。
path:针对哪个目录下有效果。
domain:域名,如果你想跨域使用cookie,必须设置这个值,比如domain=”.lawrence.com”,那么www.lawrence.com和blogs.lawrence.com和calendars.lawrence.com都可以访问到这个cookie。
httponly:如果设置为True,客户端的js代码将不能访问到cookie。
3. delete_cookie(key,path=’/’,domain=None):删除cookie。
实战
创建一个主页,如果用户已经登陆,则跳转到主页,如果用户没有登陆,则跳转到登陆页面,登陆成功后,跳转回主页.
新建项目day13
,新增应用douban
项目的目录结构如下

0.配置文件settings.py
工欲善其事,必先利其器
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'douban',
]
1.模型models.py
根据MVC架构,第一步是设计数据库的模型,设计UserModel
,包含2个字段username
,password
用来存放登陆的用户名和密码.
from __future__ import unicode_literals
from django.db import models
class UserModel(models.Model):
username=models.CharField(max_length=100)
password=models.CharField(max_length=100)
def __unicode__(self):
return self.username
国际惯例,添加了数据库模型,紧接着就是生成本地数据库文件和迁移到数据库,同时新增一条记录xiazai
,111
-
python manage.py makemigrations
-
python manage.py migrate
G:\git\web\day13>python manage.py makemigrations
Migrations for 'douban':
douban\migrations\0001_initial.py
- Create model UserModel
G:\git\web\day13>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, douban, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying douban.0001_initial... OK
Applying sessions.0001_initial... OK
G:\git\web\day13>python manage.py shell
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from douban.models import UserModel
>>> p=UserModel(username='xiazai',password='111')
>>> p.save()
2.视图函数views.py
视图函数定义了2个函数,一个是主页index
,另一个是登陆login
-
如果是通过表单提交的post请求,则首先第一步,是要获取用户输入的用户名username
,密码password
,查询数据库中是否有记录,如果没有,返回用户名和密码错误.如果有
-
获取重定向到主页的响应response=HttpResponseRedirect(reverse('index_page'))
-
用内置模块uuid创建一个全球唯一的mysessionid=str(uuid.uuid4())
-
设置客户端的cookies,response.set_cookie('mysessionid',mysessionid)
-
将数据库获取到的用户名和sessionid绑定,request.session[mysessionid]=userModel.username
-
访问主页时
-
首先要从请求的cookies中得到mysessionid的值mysessionid=request.COOKIES.get('mysessionid')
-
将这个sessionid在requst的会话里面查找,得到对应的用户名.username=request.session.get(mysessionid)
-
如果用户名username存在,则认为已经登陆,重定向到主页,否则,重定向到登陆界面.
from __future__ import unicode_literals
from django.shortcuts import render,HttpResponse,HttpResponseRedirect,reverse
from models import UserModel
import uuid
def index(request):
mysessionid=request.COOKIES.get('mysessionid')
username=request.session.get(mysessionid)
if username:
return HttpResponse("欢迎来到%s的博客!"%username)
else:
return HttpResponseRedirect(reverse('login_page'))
def login(request):
if request.method=="GET":
return render(request,'login.html')
else:
username=request.POST.get('username',None)
password=request.POST.get('password',None)
userModel=UserModel.objects.filter(username=username,password=password).first()
if userModel:
response=HttpResponseRedirect(reverse('index_page'))
mysessionid=str(uuid.uuid4())
response.set_cookie('mysessionid',mysessionid)
request.session[mysessionid]=userModel.username
return response
else:
return HttpResponse("用户名和密码错误")
3.html模板文件login.html
改页面只设计登陆表单,因为django默认开了csrf_token跨域攻击验证的中间件,所以模板文件必须加{% csrf_token %}
#day13/setting.py
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<center>
<form method="post">
{% csrf_token %}
用户名:<input type="text" name="username" placeholder="请输入用户名"/></br>
密码: <input type="password" name="password" placeholder="请输入密码"/></br>
<input type="submit" value="提交"/>
</form>
</center>
</body>
</html>
4.路由函数
这一步主要是增加2个路由,并起别名
from django.conf.urls import url
from django.contrib import admin
from douban import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$',views.index,name='index_page'),
url(r'^login/$',views.login,name='login_page'),
]
5.启动项目并调试
访问主页http://127.0.0.1:9008/,由于没登陆,所以被重定向到登陆页面http://127.0.0.1:9008/login/

如果登陆不存在的用户名,或者错误的名用户,则会提示用户名和密码错误报错了.


如果输入正确的用户名和密码,就会重定向到博客主页!再次打开,由于缓存了cookie,依然是路由到到博客主页,实验成功.

总结
cookie和session对于初学者比较难理解.这里通过简单的图例,分析了cookies和session的原理,并开发了一个登陆后可访问主页的项目.对加深理解request.COOKIES的字典对象,request.session对象,以及response.set_cookie方法有了更深入的了解.其中response.set_cookie
是服务器设置并传给客户端的mysessionid,request.session
是设置sessionid给服务器.request.COOKIES
是取出cookies中的sessionid值,进一步和服务器的request.session匹配,得到用户名username.本节课必须重点掌握.
最新评论