Cookie和Session
在不考虑数据库验证的情况下,假如通过“admin”登录,然后,在登录成功页显示“嘿,admin你好!”。这是一般系统都会提供的一个小功能,接下来我们将分别通过Cookie和Session来实现它。
Cookie机制: Cookie分发通过护展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示来提示浏览器按照指示生成想应的Cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成Cookie。而Cookie的使用刚是由浏览器按照一定的原则在后台自动发送给服务器。浏览器检查所有存储的Cookie,如果某个Cookie所声明的作用范围大于等于将要请求的资源所在位置,则把该Cookie附在请求资源的HTTP请求头上发送给服务器。
Session机制:Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
一、Cookie的使用
继续修改.../sign/views.py文件。
......
# 登录动作
def login_action(request):
if request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
if username == 'admin' and password == 'admin123':
response = HttpResponseRedirect('/event_manage/')
response.set_cookie('user', username, 3600) #添加浏览器cookie
return response
else:
return render(request,'index.html',{'error':'用户名密码错误!'})
# 发布会管理
def event_manage(request):
username = request.COOKIES.get('user', '') #读取浏览器cookie
return render(request,"event_manage.html",{"user":username})
用户登录成功后,在跳转到event_manage视图函数的过程中,通过set_cookie()方法向浏览器中添加Cookie信息。
这里给set_cookie()方法传了三个参数:
- 第一个参数“user"用于表示写入浏览器的Cookie名;
- 第二个参数username是由用户在登录页上输入用户名(即"admin");
- 第三个参数3600用于设置Cookie信息在浏览器中的保持时间,默认单位为秒。
在event_mange视图函数中,通过request.COOKIES来读取Cookie名为”user“的值。并且通过render将它和event_manage.html页面一起返回。
修改.../templates/event_manage.html页面,添加<div>标签来显示用户名。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发布会管理系统</title>
</head>
<body>
<h1>登录成功!</h1>
</body>
<div style="float: right;">
<a>嘿!{{ user }} 欢迎</a><hr>
</div>
</html>
我们登录下,看下效果。
通过F12调试,在存储里查看下Cookie信息。
二、Session的使用
Cookie固然好,但存在一定的安全隐患。Cookie像我们以前使用的存折,用户的存钱、取钱记录都会保存在这张存折上(即浏览器中会保存所有用户信息),而有非分想法的人可能会去修改存折上的数据(这个比喻忽略掉了银行服务器同样会记录用户存取款的信息)。
Session相比安全很多。Session就像是银行卡,客户拿到的只是一个银行卡号(即浏览器只保留一个Sessionid),用户的存钱、取钱记录是根据银行卡号保存在银行的系统里(即Web服务器端),只得到一个Sessionid并没有什么意义。
在Django中使用Session和Cookie类似。只需将Cookie的几步操作替换为Session操作即可。
修改.../sign/views.py文件。
......
# 登录动作
def login_action(request):
if request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
if username == 'admin' and password == 'admin123':
response = HttpResponseRedirect('/event_manage/')
#response.set_cookie('user', username, 3600) #添加浏览器cookie
request.session['user'] = username #将session信息记录到浏览器
return response
else:
return render(request,'index.html',{'error':'用户名密码错误!'})
# 发布会管理
def event_manage(request):
#username = request.COOKIES.get('user', '') #读取浏览器cookie
username = request.session.get('user', '') #读取浏览器session
return render(request,"event_manage.html",{"user":username})
再次登录,不出意外的话将会得到一个错误:
no such table: django_session
这个错误跟Session的机制有关,即然要从web服务器端记录用户的信息,那么一定要有存放用户sessionid对应信息的地方才行。所以,我们需要创建django_session表。别着急!Django已经帮我们装备好这些常用的表,只需将它们生成即可。
cmd.exe
D:\guest>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, 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 admin.0003_logentry_add_action_flag_choices... 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 auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK
通过“migrate”命令进行数据迁移。等等!我们好像并没有配置数据库,为什么已经生成了数据库表呢?这是因为Django已经默认设置SQLite3数据库。在.../settings.py 文件,查看SQLite3数据库的配置。
settings.py
......
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
......
在guest项目的根目录下已经生成了一个db.sqlite3的数据库文件,关于数据的操作将会在下一篇文章中讨论。
先来验证Session功能是否生效,重新登录。