Django学习系列(五.会话技术Cookie&Session&Token)

Posted HUTEROX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django学习系列(五.会话技术Cookie&Session&Token)相关的知识,希望对你有一定的参考价值。

前言

这篇博客为django系列,很前面的联系较为紧密.如果你是大佬,可以直接略过(如果你要指点,请评论区留言,到目前位置django学习系列已经可以说开始正式入门了,至少MVT的大部分的大致的流程已经走了一遍).在django当中,会话分为三大种,一个是非常传统的cookie技术,还有 session 技术,以及token技术

COOKIE 会话

在开始之前记住一句话,那就是cookie一定是服务器发送给客户端,并且保存在客户端的

cookie流程

示例

下面我们举个例子,做个简单的所谓的登录页面,这里为了简化流程,做个了解不会涉及到验证环节(下面的token会加入这个环节)
登录页面
login.html

<form action="/login/" method="POST">
<input name = "username" type = "text">
<button>提交<button>
</form>

minespace.html

<h2>欢迎你:{{username}}!</h2>
def login(request):
	if request.method == "GET":
		render(request,"login.html")
	elif request.method =="POST":
		username = request.POST.get("username")
		response = HttpResponse("登录成功")
		response.set_cookie('username',username)
		# 这个cookie是可以设置存活时间的,默认是关了浏览器就结束,具体可以查查就是设置一个参数,max-age
		#render也是可以设置的,那其实就是个简写,你直接看源码就看得到
		return response
def minspace(request):
	username = request.COOKIE.get("username")
	if username:
		return render(request,"minspace.html",context=locals())
	else:
		return redirect("/login/")
		# 失败就返回登录页面

退出登录

def logout(request):
	response = render(request)
	response.delete_cookie("username")
	return response

cookie加密

现在我们这个还是明文的,显然这个并不安全
这样一来一个非常简单的流程就实现了.虽然这里连简单的验证都没有.
那么加密的话也简单.
前面的设置cookie加密,然后读取的时候解密.

response.set_signed_cookied('username',username,salt="密钥")
request.get_signed_cookied("username",salt="密钥")

SEESION 会话

这个的话其实在代码上和我们的cookie类似,其实本质上也是一样的.但是区别的是,在客户端保存的cookie其实是个钥匙,这个是在django里面保存临时用户的信息的.
我们可以来看看这个表

客户端保存的cookie就是session_key字段的东西
流程如下

示例

所有的页面关系和刚刚一样

def login(request):
	if request.method == "GET":
		render(request,"login.html")
	elif request.method =="POST":
		username = request.POST.get("username")
		response = HttpResponse("登录成功")
		request.session["username"]=username
		# 这个cookie是可以设置存活时间的,默认是关了浏览器就结束,具体可以查查就是设置一个参数,max-age
		#render也是可以设置的,那其实就是个简写,你直接看源码就看得到
		return response
def minspace(request):
	
	if request.session.get("username"):
		#他会查看客户端返回的cookie然后获取username(被加密)的session_key然后到数据库去看
		#如果没有查询到那么就会报错,所以这里最好加个
		return render(request,"minspace.html",context=locals())
	else:
		return redirect("/login/")
		# 失败就返回登录页面

退出登录

def logout(request):
	response = render(request)
	#response.delete_cookie("username") 删除客户端cookie
	#del request.session["username"] 删除数据库的信息,但是这里只是删除了值,没有删除那一个行
	request.flush() #这个都操作了,并且数据库那一行直接删除 clear() 直接清空数据库
	return response

在session当中的话是可以直接输入中文的,这个是由于它做了很多转码,然后他自己做了很多加密.

这个在django当中是存到一个数据库里面的,其他的就不清楚了.同样这个也是有失效的,在数据库里面默认是14天有效.但是这个只是有效,是那个key有效,并不似会自动删除key.那个得你自己去操作.

Token 会话

这个其实是自定义一个cookie会话技术,通过前面的流程图其实已经很清楚了所谓的会话技术是什么,这个说白了就是给个用户暂时的通行证.那么为什么会诞生这玩意呢,其实还是为了满足非BS应用和移动应用.毕竟cookie这玩意只有浏览器支持.所以为了满足其他的需求我们需要不是像浏览器那样基于浏览器会自动提交cookie来验证.那么在我们其他客户端一般是使用json数据,我们返回一个字段token,这个就是我们的暂时令牌.接下来我们继续以浏览器为例自己实现个Token.当我们在例如安卓时,我们直接返回json数据带入token字段即可
例如:

data = {'msg':"hello,
		'satus':800,
		'token':token,}

我们服务端要做的就是把token给客户端,在服务器里面能够识别.至于其他的,那得去看客户端的开发者(嘿嘿就是甩锅)
现在我们来建表把完成的流程走一下.

class User(models.Model):
	user_name = models.CharField(max_length=64,unqine=ture)
	user_password = models.CharField(max_length=64)
	token = models.CharField(max_length=256)

这里直接把HTML代码省略了,反正用户就是username 密码就是 password
注册:

def register(request):
	if request.method == "GET":
		return render(request,"register.html")
	elif request.method == "POST":
		username = request.POST.get("username")
		password = requrst.POST.get("password")
		user = User.objects.filter(user_name = username)
		if user.exists():
			return render(request,"register.html")
		else:
			user = user.first()
			user.user_name=username
			user.user_password = password
			user.save()
	return HttpResponse("注册成功")

登录:

def login(request):
	if request.method=="GET":
		return render(request,"login.html")
	elif request.method == "POST":
		username = request.POST.get("username")
		password = requrst.POST.get("password")
		user = User.objects.filter(Q(user_name=username)and Q(user_password=password))
		if user.exists():
			user = user.first()
			ip = request.META.get("REMOTE_ADDR")
			token = JiaMi(ip,username)
			user.token = token
			user.save()
			response =  render(request,"minespace.html")
			response.set_cookie("token",token)
			return response
			
		else:
			#用户不对/密码
			return render(request,"login.html")
			

我们在这里定义一个简单的加密程序

def JiaMi(ip,username):
	time = time.ctime()
	return hashlib.new('md5',(ip+username+time).encode('utf-8')).hexdigest()

个人空间模块

def minespace(request):
	token = request.COOKIE.get("token")
	try:
		user = user.objects.get(token=token)
		username = user.user_name
		return return render(request,"minspace.html",context=locals())
	expect Expection as e:
		return redisrect("/login/")

minespace.html

<h2>欢迎你:{{username}}!</h2>

流程图


最后那就是删除,这还不简单.而且观察上面的流程图其实这个和我们的session很像,只是我们自己定义了加密手段,并且区别是在未来我们可以通过客户端返回json来维持会话,而不是cookie,当然我们也可以通过cookie如果支持的话.

以上是关于Django学习系列(五.会话技术Cookie&Session&Token)的主要内容,如果未能解决你的问题,请参考以下文章

{Django基础八之cookie和session}一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 dja

Django之Session与Cookie

Django中的会话技术(Cookie,Session,Token)

django-会话技术

Java开发系列-Cookie与Session会话技术

Web入门系列初探会话管理-Cookie技术