Day22-session
1. cookie: 保存在用户浏览器端的一个键值对。基于cookie做用户验证的时候,不适合把敏感信息放到cookie中。例如我们可以把user_id这个不敏感的信息放到cookie中,然后基于user_id这个不敏感的信息再在session中做一次数据库查询,再查询到敏感信息(账户余额,密码等)。这样就把保存敏感信息的任务交给了服务器端,也提高了安全性。
session:保存在服务器端的键值对,还得依赖于cookie。session在内部维护的就是一个大的字典。
下面这些信息保存在服务器端的内存里面,下次用户来的时候只需提供随机字符串,与服务器端的进行匹配。匹配成功,就可以提取此用户的敏感信息了。
2. 基于session来实现用户登录。搭建环境请参考:http://www.cnblogs.com/momo8238/p/7508677.html
3. 写 login.html, index.html 2个页面备用。
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="POST" > <input type="text" name="user" placeholder="user"/> <input type="text" name="pwd" placeholder="pwd"/> <input type="submit" value="提交"/> </form> </body> </html>
views.py
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): if request.method=='GET': return render(request,'login.html') elif request.method=='POST': user=request.POST.get('user') pwd=request.POST.get('pwd') if user=='root' and pwd=='123': return redirect('/index/') else: return render(request,'login.html') def index(request): return HttpResponse('OK')
此时没有加任何验证信息,所以直接访问index页面也是可以的。无需登录
4. 增加验证信息。
4.1 说明:
request.session['username']=user 表示设置值
request.session.setdefault('username',123)=user 表示如果值不存在,则设置默认值;如果值已经存在的话,那就不设置了。
request.session['username'] 后面没有等号,表示去session中获取值,如果不存在的话,则会报错。
request.session.get('username',None) 后面没有等号,表示去session中获取值,如果不存在的话,则返回None,不会报错。
del request.session['k1'] 表示删除值
在Django内部运行session之前,一定要先运行以下两句生成表。
python manage.py makemigrations
python manage.py migrate
4.2 运行server,如果用户名和密码正确,在浏览器端就能生成Cookies。
同时,在服务器端生成了session,Django里面的session默认是保存在数据库中的(还可以保存在文件,缓存,内存中)。打开数据库就可以看到了。后面的字符串是经过加密了的。
4.3 用户相关的信息都放到request.session里面了。如果登录成功,就在index页面显示用户名。
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): if request.method=='GET': return render(request,'login.html') elif request.method=='POST': user=request.POST.get('user') pwd=request.POST.get('pwd') if user=='root' and pwd=='123': #在session里面设置值 request.session['username']=user request.session['is_login']=True return redirect('/index/') else: return render(request,'login.html') def index(request): #获取当前用户的随机字符串 #根据随机字符串获取对应的信息 #去session中获取值,如果登录成功,显示用户名 if request.session['is_login']: return HttpResponse(request.session['username']) else: return HttpResponse('滚')
效果:
程序粘贴:
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/$', views.login), url(r'^index/$', views.index), ]
views.py
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): if request.method=='GET': return render(request,'login.html') elif request.method=='POST': user=request.POST.get('user') pwd=request.POST.get('pwd') if user=='root' and pwd=='123': #在session里面设置值 request.session['username']=user request.session['is_login']=True return redirect('/index/') else: return render(request,'login.html') def index(request): #获取当前用户的随机字符串 #根据随机字符串获取对应的信息 #去session中获取值,如果登录成功,显示用户名 if request.session['is_login']: return HttpResponse(request.session['username']) else: return HttpResponse('滚')
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="POST" > <input type="text" name="user" placeholder="user"/> <input type="text" name="pwd" placeholder="pwd"/> <input type="submit" value="提交"/> </form> </body> </html>
4.4 添加“注销“的功能:request.session.clear()
把服务器端里面的随机字符串清除掉,用户再登录的时候,就无法匹配了。
常用语法:
def index(request):
# 获取、设置、删除Session中数据
request.session['k1'] #如果不存在,则报错。
request.session.get('k1',None) #如果不存在,则返回None
request.session['k1'] = 123 #对它进行设置值,如果不存在则创建,如果存在则更新。
request.session.setdefault('k1',123) # 存在则不设置
del request.session['k1'] #删除
request.session.delete("session_key") # 删除当前用户的所有Session数据
# 所有 键、值、键值对
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
# 用户session的随机字符串
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查用户session的随机字符串 在数据库中是否
request.session.exists("session_key")
del request.session['k1'] #删除掉某一条数据
request.session.clear() #注销的时候,执行这句
request.session.delete("session_key") # 删除当前用户的所有Session数据
request.session.delete("request.session.session_key") # 删除当前用户的所有Session数据
示例效果:
需要说明的地方:
request.session.clear()-------清空session中的所有数据
request 包含了用户发来的所有数据,可以通过
<h1>欢迎登录:{{request.session.username}}</h1> 直接在前端获取到username的值
views.py
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): if request.method=='GET': return render(request,'login.html') elif request.method=='POST': user=request.POST.get('user') pwd=request.POST.get('pwd') if user=='root' and pwd=='123': #生成随机字符串,写到浏览器cookie中,保存在session中。在随机字符串对应的字典中设置相关内容... # 在session里面设置值 request.session['username']=user request.session['is_login']=True return redirect('/index/') else: return render(request,'login.html') def index(request): #获取当前用户的随机字符串 #根据随机字符串获取对应的信息 #去session中获取值,如果登录成功,显示用户名 if request.session.get('is_login',None): #return HttpResponse(request.session['username']) return render(request,'index.html',{'username':request.session['username']}) else: return HttpResponse('滚') def logout(request): request.session.clear() return redirect('/login/')
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>欢迎登录:{{username}},{{request.session.username}}</h1> <a href="/logout/">注销</a> </body> </html>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="POST" > <input type="text" name="user" placeholder="user"/> <input type="text" name="pwd" placeholder="pwd"/> <input type="submit" value="提交"/> </form> </body> </html>
urls.py
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/$', views.login), url(r'^index/$', views.index), url(r'^logout/$', views.logout), ]
4.5 给sessionid 设置超时时间。
在django里面默认session的超时时间是2周,
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略
人为设置超时时间的效果:
代码:
views.py
from django.shortcuts import render,HttpResponse,redirect # Create your views here. def login(request): if request.method=='GET': return render(request,'login.html') elif request.method=='POST': user=request.POST.get('user') pwd=request.POST.get('pwd') if user=='root' and pwd=='123': #生成随机字符串,写到浏览器cookie中,保存在session中。在随机字符串对应的字典中设置相关内容... # 在session里面设置值 request.session['username']=user request.session['is_login']=True if request.POST.get('remember',None)=='1': #设置超时时间 request.session.set_expiry(10) return redirect('/index/') else: return render(request,'login.html') def index(request): #获取当前用户的随机字符串 #根据随机字符串获取对应的信息 #去session中获取值,如果登录成功,显示用户名 if request.session.get('is_login',None): #return HttpResponse(request.session['username']) return render(request,'index.html',{'username':request.session['username']}) else: return HttpResponse('滚') def logout(request): request.session.clear() return redirect('/login/')
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>欢迎登录:{{username}},{{request.session.username}}</h1> <a href="/logout/">注销</a> </body> </html>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="/login/" method="POST" > <input type="text" name="user" placeholder="user"/> <input type="text" name="pwd" placeholder="pwd"/> <input type="checkbox" name="remember" value="1"/> 10秒免登录 <input type="submit" value="提交"/> </form> </body> </html>
修改默认超时时间---在setting里面做修改。
每次用户发来请求的时候,都需要更新一下超时时间。超时时间的起点应该是每次用户操作完开始计算,而不应该是第一次登录的时间点为起点。
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)。最后一次操作10秒后再失效。
a. 配置 settings.py
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认)
SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
set_cookie('k',123) #没有写超时时间,默认情况下就是关闭浏览器,cookie失效。
SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)
5.session的基本操作
. Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:
- 数据库(默认) #把session存在数据库中
- 缓存
- 文件
- 缓存+数据库
- 加密cookie
数据库session
Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认) b. 使用 def index(request): # 获取、设置、删除Session中数据 request.session['k1'] request.session.get('k1',None) request.session['k1'] = 123 request.session.setdefault('k1',123) # 存在则不设置 del request.session['k1'] # 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() request.session.iterkeys() request.session.itervalues() request.session.iteritems() # 用户session的随机字符串 request.session.session_key # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") # 删除当前用户的所有Session数据 request.session.delete("session_key")
缓存session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https传输cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存
文件session
配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 SESSION_COOKIE_SECURE = False # 是否Https传输cookie SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期 SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存 b. 使用 同上
缓存+数据库Session
数据库用于做持久化,缓存用于提高效率。先去数据库中找,找到的话,直接用;找不到的话,到数据库中去找,然后再在缓存中放一份。
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 b. 使用 同上
加密cookie Session
a. 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 b. 使用