一、Session和Cookies
1.Session在计算机中,尤其是在网络应用中,称为"会话控制".session对象存储特定用户会话所需要的属性及配置信息.这样,当用户在应用程序的web页之间请求跳转时,储存在session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去.当用户请求来自应用程序的web页时,如果该用户还没有会话,则web服务器将自动创建一个session对象.当会话过期或被放弃后,服务器将终止该会话
2.Cookie是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术.Cookies是当你浏览某网站时,由Web服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。当你再次来到该网站时,网站通过读取Cookies,得知你的相关信息,就可以做出相应的动作,如在页面显示欢迎你的标语,或者让你不用输入ID、密码就直接登录等等。
3.cookie 和session 的区别:
<2>cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
<3>、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
<4>单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
cookie 和session 的联系:
session是通过cookie来工作的
session和cookie之间是通过$_COOKIE['PHPSESSID']来联系的,通过$_COOKIE['PHPSESSID']可以知道session的id,从而获取到其他的信息。
在购物网站中通常将用户加入购物车的商品联通session_id记录到数据库中,当用户再次访问是,通过sessionid就可以查找到用户上次加入购物车的商品。因为sessionid是唯一的,记录到数据库中就可以根据这个查找了。
二、登录成功将用户信息放入session
在我们登陆成功之后,我们需要把用户信息显示在页面上,并且在跳转到别的页面的时候,这个用户依然是已经登录的状态浏览器可以识别,这就需要session会话作用域
在Django中使用session步骤:
1.在setting.py中找到installed_apps
2.中间件(帮我们启用session)
3.设置存储形式(储存在设置数据库中)
我们需要把app的session在数据库中创建一个表,使用shell命令 migrate sessions
我们会发现数据库中创建了一个session的表用来储存session的创建时间和到期时间 (默认时间为两周)
4.引用request.session
session智能储存json也就是字典类型的数据
Django session的设计原理:
a.如果用户是第一次请求(就看客户端ie是否保存了 sessionID的cookie)
创建session model
生成一个key sessionId 随机的一个字符串(uuid使id永远也不会重复)
保存到你的session_engine指定位置
保存到cookie中,在客户的浏览器中
b.如果第二次以上的请求,客户端ie都会自动提交cookie到django中,django中利用你配置的
SessionMiddleware中间件激活session利用cookie中的sessionID到session_engine指定位置读取session model,并设置到request的session属性上
正是这样才能在view里面通过request.session使用session能力
session本省就是一个dict字段
session在存数据时数据必须支持序列化json
(补充说明Django中的重定向, 是重新发起一个新的url请求到url分发器,不能带参数到页面,再由view做传递参数到页面的工作)
创建一个welcome2页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>session 登录页面</h1>
<h1>欢迎{{ user.username }}访问本页面</h1>
</body>
</html>
在views中修改函数
def welcome2(request):
user=request.session.get('user')
return render(request, 'user/welcome2.html',{"user":user})
def login(request):
if request.method == 'GET':
return render(request, 'user/login.html', {})
elif request.method == 'POST':
unname=request.POST.get('uname')
upwd=request.POST.get('upwd')
bloguserSet = BlogUser.objects.filter(userName=unname,passWord=upwd)
if len(bloguserSet) == 1:
#把当前登录用户的名字存在session中
#session的获取
session=request.session
userName=bloguserSet.first().userName
session["user"]={"username":userName}
return redirect(reverse('user:welcome2'))
else:
return render(request,'user/login.html',{"error":"用户名或密码错误"})
在urls.py中修改路径
# usr/bin/python
# -*-coding:utf-8-*-
from django.urls import path
from blog_user import views
app_name = 'user'
urlpatterns = [
path('register', views.register),
path('welcome/<int:id>/', views.welcome, name='welcome'),
path('welcome2', views.welcome2, name='welcome2'),
path('hasName',views.hasName),
path('login',views.login),
]
进入浏览器输入正确用户名
5.然后我们关闭浏览器,再次打开浏览器,在地址栏输入http://127.0.0.1:8001/user/welcome2 会发现内容不变
当我们把浏览器的cookie清除,再次输入http://127.0.0.1:8001/user/welcome2时 会发现用户名消失了 ,说明绘画是通过cookie和session共同保存的,cookie是保存在浏览器里的,session保存在数据库中
接下来我们来实现不登录的话看不到welcome这个页面,如果不登录,直接访问welcome2页面时就会出现请登录超链接
我们需要在views.py中添加退出函数
def logout(request):
#session失效
request.session.flush()
return redirect(reverse('user:welcome2'))
在urls中配置路径
# usr/bin/python
# -*-coding:utf-8-*-
from django.urls import path
from blog_user import views
app_name = 'user'
urlpatterns = [
path('register', views.register),
path('welcome/<int:id>/', views.welcome, name='welcome'),
path('welcome2', views.welcome2, name='welcome2'),
path('hasName',views.hasName),
path('login',views.login),
path('logout',views.logout),
]
在welcome2.html中做一个判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>session 登录页面</h1>
{% if user is not None %}#如果session中的user不为空进入欢迎页面
<h1>欢迎{{ user.username }}访问本页面
<a href="logout">退出</a>#退出后进入请登录界面
</h1>
{% else %}
<a href="login">请登录</a>#点击进入登录页面
{% endif %}
</body>
</html>
登录成功后
三、创建个人中心页面和主页面
我们创建两个页面放在welcome2中, 一个a.html,一个b.html
要求:进入welcome2页面时,出现a页面超链接和b页面超链接
a:个人中心页面,必须登录才能进入,点击超链接如果登录则进入个人中心,如果未登录返回登录页面,并且记录跟人中心页面登录后自动跳转个人中心页面
b:主页面 无论有没有登录都可以访问
1.我们在templates/user下创建 a.html b.html在welcome2.html中加入超链接
a.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
个人中心,必须登录
</body>
</html>
b.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
博客主页面,可以不登录
</body>
</html>
welcome2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>session 登录页面</h1>
{% if user is not None %}
<h1>欢迎{{ user.username }}访问本页面
<a href="logout">退出</a>
</h1>
{% else %}
<a href="login">请登录</a>
{% endif %}
<a href="a">个人中心</a>
<a href="b">主页面</a>
</body>
</html>
2.在views.py中写入函数
def a(request):
#判断 user 是否在session中
if 'user' in request.session:
#登录 跳转到a页面
return render(request, 'user/a.html', {})
else:
#没有登录 记录下目标页
session=request.session
session["uri"]=request.get_raw_uri()
return redirect(reverse('user:login'))
def b(request):
return render(request, 'user/b.html', {})
然后对登录login函数进行,如果记录了其他页面,登录后直接进入记录页面
#登录
def login(request):
if request.method == 'GET':
return render(request, 'user/login.html', {})
elif request.method == 'POST':
unname=request.POST.get('uname')
upwd=request.POST.get('upwd')
bloguserSet = BlogUser.objects.filter(userName=unname,passWord=upwd)
if len(bloguserSet) == 1:
session=request.session
userName=bloguserSet.first().userName
session["user"]={"username":userName}
#此处应该做一个判断如果记录页面函数uri中由记录则进行跳转
#如果uri中没有储存则给一个welcome2地址
uri=session.get('uri','/user/welcome2')
return redirect(uri)
else:
return render(request,'user/login.html',{"error":"用户名或密码错误"})
3.配置路径blog_user/urls.py
from django.urls import path
from blog_user import views
app_name = 'user'
urlpatterns = [
path('register', views.register),
path('welcome/<int:id>/', views.welcome, name='welcome'),
path('welcome2', views.welcome2, name='welcome2'),
path('hasName',views.hasName),
path('login',views.login,name='login'),
path('logout',views.logout),
path('a',views.a),
path('b',views.b),
]