django cookie session
我们要写一个cmdb被称为运维资源管理系统,BIM流程管理平台,类似这样的项目,很重要的点,就是用户画像,我们来描述参与业务的主体,和之间的关系。在这样的项目当中:用户和权限就显得尤为重要。但是仔细考虑,我们首先要解决的问题不是用户的权限问题,而是用户可持续访问的问题,在学习django之初,各位就听过,http请求是无状态的,前后两次请求没有必然联系,通俗的说:刷新页面,之前请求的内容就没有了。为了保证用户的可持续访问:
前辈们首先研发了cookie(曲奇):通俗的来说cookie就是服务器下发给用户用来校验身份的证明
类似:西游记当中的通关文牒
Cookie 核心点
1、 cookie的生成
cookie在django当中使用set_cookie来设置。
常用参数如下:
max_age | Cookie有效期,生命周期 单位 秒 3600 |
expires | Cookie 的过期时间和max_age冲突 |
Path | 指定的url访问到cookie |
domain | 指定域名可以访问cookie |
secure | 如果为true代表https |
cookie的使用
我们在设置和调用cookie的时候,我们有两种方法
1、 普通cookie
2、 加盐cookie
Session
Session的出现是为了弥补cookie的缺陷。cookie解决无连接问题,但是暴露了大量的安全问题,由于是下发用户本地的,所有存在很多问题,比如:
1、 用户拒绝接受cookie
2、 其他盗用,冒用cookie
3、 用户修改cookie
4、 等
由于以上多种问题,我们引入session,我们将用户的信息保存到服务器上,下发给用户cookie当中的只是一个session_id.
我们来看一下cookie加session的工作原理
1、 用户访问,服务端生成随机字符串
2、 当用户登录成功,把session_id也就是上面生成的随机数组成键值对:
{session_id:”12asdasdas1i13i123”}
发送给用户
3、 服务器发送之后,用户保存
我们得出结论:
Session(会话)是要依赖cookie,
Session实质上是一种特殊的cookie
django 登录、登出
首先我们先修改我们的登录页面
/template/login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>艾伦沃克尔CMDB-登录</title>
<!-- Bootstrap Core CSS -->
<link href="/static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<!-- MetisMenu CSS -->
<link href="/static/vendor/metisMenu/metisMenu.min.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="/static/dist/css/sb-admin-2.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="/static/vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="login-panel panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">欢迎登录艾伦沃克尔CMDB系统</h3>
</div>
<div class="panel-body">
<form role="form" method="post" action="/login/">
{% csrf_token %}
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="账号" name="username" type="text" autofocus>
</div>
<div class="form-group">
<input class="form-control" placeholder="密码" name="password" type="password" value="">
</div>
<div class="checkbox">
<label>
<input name="remember" type="checkbox" value="Remember Me">记住我
</label>
</div>
<p style="color:red">{{ result.data }}</p>
<!-- Change this to a button or input when using this as a form -->
{# <a href="/index/" class="btn btn-lg btn-success btn-block">登录</a>#}
<input class="btn btn-lg btn-success btn-block" type="submit" value="登录">
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- jQuery -->
<script src="/static/vendor/jquery/jquery.min.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="/static/vendor/bootstrap/js/bootstrap.min.js"></script>
<!-- Metis Menu Plugin JavaScript -->
<script src="/static/vendor/metisMenu/metisMenu.min.js"></script>
<!-- Custom Theme JavaScript -->
<script src="/static/dist/js/sb-admin-2.js"></script>
</body>
</html>
视图函数
\ALLENCMDB\ALLENCMDB\views.py
def login(request):
return render_to_response("login.html")
\ALLENCMDB\ALLENCMDB\urls.py
from django.conf.urls import include, url
from django.contrib import admin
from ALLENCMDB.views import *
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^ckeditor/',include('ckeditor_uploader.urls')),
url(r'^user/', include("User.urls")),
url(r'^base/$',base),
url(r'^index/$',index),
url(r'^login/$',login),
]
cookie的基本使用套路
我们想象的是发送账号和密码请求服务器登录,服务器校验成功下发cookie。实际上,我们请求登录页,就开始下发cookie,我们发送账号和密码请求登录页是带着cookie
普通的设置cookie
\ALLENCMDB\views.py
def login(request):
# 生成response实例
response = render(request,"login.html")
# 设置cookie
response.set_cookie("login_cookie","helloworld",max_age=3600)
return response
加盐cookie设置
def login(request):
# 生成response实例
response = render(request,"login.html")
# 设置加盐cookie
response.set_cookie("login_cookie","helloworld",salt="nihao",max_age=3600)
return response
从上面可以看出,加盐与普通cookie的区别就是加盐cookie在cookie=”helloworld”后面多了一串不规则的字符串
获取普通的cookie
login_cookie = request.COOKIES.get("login_cookie")
取出加盐的cookie
login_cookie = request.get_signed_cookie(key = "valid",salt = "nihao")
登录视图函数代码
\ALLENCMDB\views.py
def login(request):
if request.method == "POST" and request.POST:
#获取校验cookie
login_cookie = request.get_signed_cookie(key="valid",salt="nihao")
if login_cookie:
data = request.POST
username = data.get("username")
password = data.get("password")
try:
user = CMDBUser.objects.get(username=username)
except:
return HttpResponse("用户名不存在")
else:
db_password = user.password
if password == db_password:
response = HttpResponseRedirect("/index/",locals())
response.set_cookie(key="valid",value=user.username)
return response
else:
return HttpResponse("密码错误")
else:
return HttpResponse("404,你访问的页面不存在")
else:
# 生成response实例
response = render(request,"login.html")
# 设置cookie
# response.set_cookie("valid","login_cookie",max_age=3600)
# 设置加盐cookie
response.set_signed_cookie("valid","login_cookie",salt="nihao",max_age=3600)
return response
上面的登录是没有问题的,但是我们不通过登录,直接访问index也可以,也就是说我们安装大门,没有砌墙。所有用户在访问index之前,需要被校验,校验是否具有cookie,这个校验使用的地方太多。所以我们用装饰器来写校验。
装饰器视图函数
\ALLENCMDB\views.py
def loginValid(func):
def valid(request,*args,**kwargs):
username = request.COOKIES.get("valid")
if username:
try:
user = CMDBUser.objects.get(username=username)
except:
return HttpResponseRedirect("/login/",locals())
else:
return func(request)
else:
return HttpResponseRedirect("/login/",locals())
return valid
@loginValid
def index(request):
return render(request,'index.html')
除了上述所说的登录需要cookie的校验,当然我们工作当中还需要在我们登出时,需要将我们的cookie进行删除,跳转到我们的登录界面
def logout(request):
valid = request.COOKIES.get("valid")
response = HttpResponseRedirect("/login/")
if valid == "login_cookie":
response.delete_cookie("valid")
return response
当我们在点击注销登录时,会自动删除我们的cookie值,并且再次访问我们的页面时会自动跳转到登录页面。
以上还有一个可以优化的地方就是,用户密码在进行入库时可以利用md5算法进行加密后再入库,这样数据库中也是加密后的密码。