一、 Cookie和Session的发展史
一开始:只有一个页面,没有登录功能,大家看到东西都一样
新闻
时代发展,出现了需要登录注册的网站,要有一门技术存储我们的登录信息
京东、天猫
cookie
存储形式:k:v键值对
存储位置:客户端
不安全,信息可能会泄露
时代发展,需要有一门新的安全的技术
session
标识符,来表示我是当前用户加密出来的数据
对敏感信息进行加密处理
存储服务端:
标识符配合上你的加密串
把我的标识符+ 字符串全给客户端
客户端存储格式
session_id:返回回来的表示符+加密串
token
三段式加密
二、Cookie
2.1 设置cookie
HttpResponse
render
redriectobj = HttpResponse("ok")
obj.set_cookie('k','v')
def login(request, *args, **kwargs): if request.method == 'POST': username = request.POST.get("username") password = request.POST.get("password") if username == "dream" and password == "521": obj = HttpResponse("ok") obj.set_cookie('sign', 'user') return obj else: return redirect('/login/') return render(request, 'login.html')
2.2 取值
cookie取值验证:
def home(request, *args, **kwargs): sign = request.COOKIES.get('sign') if sign and sign == 'user': return HttpResponse("这是home页面") else: return redirect('/login/')
完整版 cookie登录注册:
def login(request, *args, **kwargs): # next_url = request.get_full_path() # print(next_url) # /login/?next_url=/home/ if request.method == 'POST': username = request.POST.get("username") password = request.POST.get("password") if username == "dream" and password == "521": next_url = request.GET.get('next_url') # print(next_url) # /home/ obj = redirect(next_url) obj.set_cookie('sign', 'user') return obj else: return redirect('/login/') return render(request, 'login.html') def login_auth(func): def inner(request, *args, **kwargs): # print(request.path_info) # /home/ # print(request.get_full_path()) # /home/?username=111 next_url = request.get_full_path() # /home/ # print(next_url)# /home/ sign = request.COOKIES.get('sign') if sign and sign == 'user': res = func(request, *args, **kwargs) return res else: return redirect(f'/login/?next_url={next_url}') return inner @login_auth def home(request, *args, **kwargs): return HttpResponse("这是home页面") # def home(request, *args, **kwargs): # sign = request.COOKIES.get('sign') # if sign and sign == 'user': # return HttpResponse("这是home页面") # else: # return redirect('/login/') @login_auth def index(request, *args, **kwargs): return HttpResponse("这是index页面")
2.3 设置过期时间
obj.set_cookie('sign', 'user', expires=3) obj.set_cookie('sign', 'user', max_age=3)
2.4 刪除cookie
def logout(request, *args, **kwargs): obj = redirect('/home/') # 设置超时时间 5s 到期 obj.delete_cookie('sign') return obj
三、 Session
3.1 设置session
request.session['sign'] = 'user'
3.2 取值session
sign = request.session.get('sign')
def login(request, *args, **kwargs): # next_url = request.get_full_path() # print(next_url) # /login/?next_url=/home/ if request.method == 'POST': username = request.POST.get("username") password = request.POST.get("password") if username == "dream" and password == "521": # next_url = request.GET.get('next_url') # print(next_url) # /home/ request.session['sign'] = 'user' obj = redirect('/home/') # 设置过期时间 # obj.set_cookie('sign', 'user', expires=3) # obj.set_cookie('sign', 'user', max_age=3) return obj else: return redirect('/login/') return render(request, 'login.html') def login_auth(func): def inner(request, *args, **kwargs): # print(request.path_info) # /home/ # print(request.get_full_path()) # /home/?username=111 next_url = request.get_full_path() # /home/ # print(next_url)# /home/ sign = request.session.get('sign') # print(sign) # user if sign and sign == 'user': res = func(request, *args, **kwargs) return res else: return redirect(f'/login/?next_url={next_url}') return inner @login_auth def home(request, *args, **kwargs): return HttpResponse("这是home页面")
注:
session基于数据库表才能使用的
必须先迁移数据库,生成 django_session 表
session只对当次登录有效
主动清除浏览器中本地存在的session
验签发现,没有sessionid就会自动生成新的session
django_sessoin
表中的数据条数取决于浏览器同一个计算机(IP地址)上同一个浏览器只会有一条数据生效
同一个计算机(IP地址)上多个浏览器会有多个数据生效
当session过期的时候,可能会出现多条数据对应一个浏览器
但是这些数据不会持久化存储,会被定时清理掉,可以手动清除也可以代码清除
目的是为了节省服务器数据库资源
3.3 session设置过期时间
request.session['sign'] = 'user' # 如果是数字的话就是指定 s shu # request.session.set_expiry(3) # 0 就是关闭浏览器后自动清除浏览器的sessionid request.session.set_expiry(0)
3.4 删除session
# 删除session方式一 # request.session.delete() # 把浏览器和数据库里面的session全部清除掉 request.session.flush()
四、 CBV加装饰器的三种方法
4.1 方式一:加载视图函数上面
@method_decorator(login_auth) def get(self, request, *args, **kwargs): return HttpResponse("这是home页面") def post(self): ...
4.2 方式二:放在类视图上面 (放的装饰器函数,name指定你的视图函数里面的方法)
@method_decorator(login_auth, name='get') @method_decorator(login_auth, name='post') class UserView(View):
4.3 方式三 : dispactch 方法加装饰器 : 本视图函数内所有的视图都需要走装饰器
@method_decorator(login_auth) def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. 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)