前言:
前面我的博客登录成功之后,把用户名存储在客户端session里,并且在退出登录的时候,并没有真正地删除数据库里的session,只是把浏览器上的表面数据给删除了,这样子短时间内没什么问题,但是时间久了,随着用户登录次数变多,多出次数变多,我们的数据库会生成很多的sessionid,像这样:
我之前测试了几次,就生成几个sessionid,而退出的时候根本就没有扔掉这些数据!导致他们永远地存在了数据库中!
这是因为
session
其实是依赖于
cookie
的每次我们往
session
里存数据,数据库会自动生存一个字段为
django_session
的表存储
sessionid
,这个id以
cookie
的形式作为我们取数据的凭证,而我们前面用的
logout(request)
方法只是删掉了浏览器上的cookie,这样子数据库的sessionid就会一直存在了
COOKIE、SESSION、TOKEN的区别
在进入正题之前我们先了解一下这三个存储缓存方法的区别:
COOKIE:
cookie是客户端会话技术,数据存储在客户端
优点:干净,容易操作,服务器压力少
缺点:不安全,一些重要私密数据不能存在cookie
SESSION:
session是服务端会话技术,数据存储在服务器中,依赖于cookie
优点:安全,简洁
缺点:操作起来有点麻烦,而且不适用于移动端等没有session的地方
TOKEN:
token是服务端会话技术,其实就是自定义的session
优点:安全,适用于移动端等没有session的地方
缺点:操作起来有点麻烦
其实如果只是用于浏览器,只要删除语句得当,我们的登录用session就足够了!
如果是
response = redirect(reverse(\'/\'))response.delete_cookie(\'sessionid\')
我们只删除了浏览器的cookie,这样久而久之,数据库会因为垃圾数据过多而运行缓慢!
如果是
del request.session[\'username\']
我们只删除了数据库中对应sessionid的值删了,sessionid和cookie依旧存在,这样也是产生垃圾数据的方式!
正确方式是
request.session.flush()
如果是用于浏览器,上面这个flush方法就够了,但是如果要用于移动端或者客户端,session用不了
-
首先,我们在model.py的Player模型里添加一条
可以看到,token是存储在数据库里面的
写完之后,需要我们手动给数据表添加字段
https://jingyan.baidu.com/article/636f38bb266082d6b84610d7.html
这个链接详细讲述了如何添加字段 -
我们的token肯定是像大部分密钥一样是一串奇奇怪怪的字符串
#生成一段唯一的token值def generate_token(ip,username):now_time = time.ctime()rand = usernamereturn hashlib.new(\'md5\',(ip+now_time+rand).encode(\'utf-8\')).hexdigest()
用这个方法就可以形成一段奇奇怪怪的字符串啦!
-
可以看到我们的
token
存入数据库时,最开始是
null
的形式,并且我们登陆不可能只登陆一次,需要频繁地进行登陆退出的操作,所以我们需要利用update语句来对数据库数据进行更新,如果只是单纯地存入,第二次登陆的时候,数据库里的数据将不会改变,然后拿数据的时候就无法根据实时的token来校对拿取数据了
if user[0].password == password:ip = request.META.get(\'REMOTE_ADDR\')token = generate_token(ip, username)user.update(p_token=token) #更新数据库数据response = HttpResponseRedirect(\'/\')response.set_cookie(\'token\',token)return response
这里的ip获取到的是每个用户电脑的地址,保证了token的唯一性
然后我们把token更新至user里面,然后把token设置到cookie里面,再重定向到首页 -
首页拿取数据我写到一个函数里面,这样后面只需要调用函数就可以获得用户名的值,保证了代码的简洁
def zhanname(request):token = request.COOKIES.get(\'token\')print(token)if token == None:denglu = \'游客\'else:user = Player.playObj.filter(p_token=token)if user.first() == None:denglu = \'游客\'else:print(user.first())denglu = user.first().usernamereturn denglu
利用cookie拿到token,然后再从数据库取对应的数据
其实大多时候,token都是以json的样式发送到客户端的,形式如下:
data = {\'status\': 200,\'msg\': \'get success\',\'token\': token,}return JsonResponse(data=data)
token = request.GET.get(\'token\')data = {\'status\': 200,\'msg\': \'get success\',\'data\':{\'denglu\':denglu}}return JsonResponse(data=data)
这就是客户端的正确写法
TOKEN的退出登录
既然token是依存在cookie的,那么我们退出登录就只需要删除cookie就行啦,不用担心会生成多余的垃圾数据,因为token是不想session一样自己一个表,每次创建生成一个sessionid,他是存在于某个表里的一个字段,删除cookie之后,就算是退出了!