Cookie和Session
1.Cookie和Session介绍
1.1 Cookie
- 服务器保存在客户端浏览器上的信息都可以称之为cookie
- 指代服务端让客户端保存的数据(存储在客户端上与用户信息相关的数据)
- 它的表现形式一般都是k:v键值对(可以有多个)
1.2 Session
- 保存在服务器上的信息都可以称之为session
- 指代服务端保存的跟用户信息相关的数据
- 它的表现形式一般都是 session_id :随机的字符串
2. Django操作Cookie
2.1 视图函数的返回值(三板斧)
- 正常返回三板斧对象
return HttpResponse()
return render()
return redirect()
- 变形
obj = HttpResponse()
return obj
obj1 = render()
return obj1
obj2 = redirect()
return obj2
如果想要操作cookie,必须进行以上变形才可以
2.2 设置cookie
# 1.获取响应对象
obj = HttpResponse("注册成功")
# 2.设置cookie
# max_age=5,设置超时时间 5s 到期
obj.set_cookie(key,value,max_age=5)
# 3.获取cookie
cookie = request.COOKIES.get('key')
# 4.删除注销cookie
obj.delete_cookie("key")
return obj
3.登陆功能实现
(1)简单实现
- 路由
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('home/', views.home),
]
- 视图
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == "dream" and password == "521":
# 登陆成功之后,跳转到登陆成功之后才能看到的页面
return redirect('/home/')
return render(request, 'login.html')
def home(request):
return HttpResponse("登陆成功!")
- 前端
<form action="" method="post">
<p>username:<input type="text" name="username" class="form-control"></p>
<p>password:<input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-success">
</form>
- 问题
- 登陆成功之后的跳转页面,不需要登陆也可以直接访问到,只需要给对应的地址即可
(2)解决登陆问题
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == "dream" and password == "521":
# 登陆成功之后,保存用户登陆状态
obj = redirect('/home/')
# 让浏览器记录cookie
obj.set_cookie("sign", "1314521")
'''
浏览器不单单只是帮我们保存cookie
而且在后面每次访问的时候都会带着cookie
'''
# 登陆成功之后,跳转到登陆成功之后才能看到的页面
return obj
return render(request, 'login.html')
def home(request):
# 读取携带的cookie,cookie正确登陆成功
if request.COOKIES.get("sign") == "1314521":
return HttpResponse("登陆成功!")
# 读取携带的cookie,cookie不正确跳转到登陆页面
return redirect('/login/')
(3)迭代-登陆认证装饰器
- 用户如果没有登陆的情况下想访问一个需要登录的页面
- 那么先跳转到登录页面,当用户输入正确的用户名和密码之后
- 再跳转到用户之前想访问的页面去,而不是直接写死
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
if username == "dream" and password == "521":
# 获取用户上一次想要访问的url
# 结果可能为空 -- 直接访问login
tag_url = request.GET.get('tag_url')
if tag_url:
obj = redirect(tag_url)
else:
# 登陆成功之后,保存用户登陆状态
obj = redirect('/home/')
# 让浏览器记录cookie
obj.set_cookie("sign", "1314521")
'''
浏览器不单单只是帮我们保存cookie
而且在后面每次访问的时候都会带着cookie
'''
# 登陆成功之后,跳转到登陆成功之后才能看到的页面
return obj
return render(request, 'login.html')
# 校验用户登录状态的装饰器
def auth_check(func):
def inner(request, *args, **kwargs):
# 获取到用户上一次想要访问的url
tag_url = request.get_full_path()
# 读取携带的cookie,cookie正确登陆成功
if request.COOKIES.get("sign") == "1314521":
res = func(request, *args, **kwargs)
return res
else:
# 读取携带的cookie,cookie不正确跳转到登陆页面
return redirect(f'/login/?next={tag_url}')
return inner
@auth_check
def home(request):
return HttpResponse("home登陆成功!")
@auth_check
def index(request):
return HttpResponse("index登陆成功!")
@auth_check
def func(request):
return HttpResponse("func登陆成功!")
4.Django操作session
- Django使用session的前提是已经迁移过数据库并且数据库中有 django_session 这张表
- Django的session默认过期时间是 14 天
def login(request):
if request.method == "POST":
data = request.POST
username = data.get("username")
password = data.get("password")
if username == "dream" and password == "521":
# request.session["sign"] = "6666"
# request.session["sign"] = "777"
request.session["sign"] = "888"
# 产生了一个随机的字符串
# 把这个随机字符串跟加密的数据绑定在一起
# 将这个随机字符串发送给客户端
# 如果session中放入多个值的情况下
# 默认采用最后一个session值而不是第一个
# 设置过期时间
# request.session.set_expiry(3)
# 如果是数字的话,过期时间就是在指定 秒数后过期
# request.session.set_expiry(0)
# 如果参数是数字 0 ,过期时间是随着浏览器的关闭后,session 会直接过期
#
obj = HttpResponse("登陆成功")
return obj
return HttpResponse("登录失败")
return render(request, "login.html", locals())
def index(request):
sign = request.session.get("sign")
if sign and sign == "888":
return HttpResponse("index")
return redirect("login")
def logout(request):
print(request.session.get("sign"))
# request.session.delete()
# 该方法用于删除当前用户的Session数据,但会保留Session的Key。
# 这意味着Session对象本身仍然存在,但其中的数据将被清空。
# 下次访问时,如果Session没有被重新填充,则会得到一个空的Session对象。
request.session.flush()
# 该方法用于完全删除当前用户的Session,包括Session对象和所有相关数据。
# 下次访问时,将创建一个新的空Session对象。
print(request.session.get("sign"))
return redirect("login")
5. 给CBV添加装饰器的三种方式
from django.views import View
from django.utils.decorators import method_decorator
def login(request):
if request.method == "POST":
data = request.POST
username = data.get("username")
password = data.get("password")
next_url = request.GET.get("next_url")
if username == "dream" and password == "521":
if next_url:
obj = redirect(next_url)
else:
obj = HttpResponse("登陆成功")
obj.set_cookie("sign", "666")
return obj
return HttpResponse("登录失败")
return render(request, "login.html", locals())
def home(request):
# 获取cookie"
sign = request.COOKIES.get("sign")
if sign and sign == "666":
return HttpResponse("这是正常的home页面")
return redirect("login")
def login_auth(func):
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
sign = request.COOKIES.get("sign")
if sign and sign == "666":
obj = func(request, *args, **kwargs)
return obj
return redirect(f"/login/?next_url={next_url}")
return inner
# CBV加装饰器方式二 : 在类上面加 @method_decorator(装饰器函数名,指定给哪个视图函数加装饰器)
# @method_decorator(login_auth, "get")
class Index(View):
# CBV加装装饰器的方式三 : 直接重写父类的 dispatch方法,但是这种方法有弊端,弊端就是所有的视图函数都会收到影响
@method_decorator(login_auth)
def dispatch(self, request, *args, **kwargs):
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
# CBV 加装饰器方式一 : 直接在类视图上面 加 @method_decorator(装饰器函数名)
# @method_decorator(login_auth)
def get(self, request):
return HttpResponse("这是正常的index页面")
标签:return,get,request,sign,Session,Cookie,cookie,login
From: https://www.cnblogs.com/Formerly/p/18102500