一、cookie和session介绍
cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。
cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。
cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。
总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本。
二、cookie的简单使用
1、获取Cookie
request.COOKIES.get("islogin",None) #如果有就获取,没有就默认为none
2、设置Cookie
obj = redirect("/index/")
obj.set_cookie("islogin",True) #设置cookie值,注意这里的参数,一个是键,一个是值
obj.set_cookie("haiyan","344",20) #20代表过期时间
obj.set_cookie("username", username)
3、删除Cookie
obj.delete_cookie("cookie_key",path="/",domain=name) #path定义的是对那些路径生效,/表示对所有的url路径
4、cookie的优缺点
优点:数据存储在客户端。减轻服务端的压力,提高网站的性能
缺点:安全性不高,在客户端很容易被查看或破解用户会话信息
5、cookie登录示例
models.py文件内容:
class UserInfo(models.Model):
username =models.CharField(max_length=32)
password =models.CharField(max_length=32)
urls.py文件内容:
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,redirect,HttpResponse
from app01 import models
def login(request):
if request.method=="POST":
print("所有请求数据",request.POST)
username = request.POST.get("username")
password = request.POST.get("password")
ret = models.UserInfo.objects.filter(username=username,password=password) #判断用户输入的是否是数据库中的值
if ret: #如果用户名和密码都正确,则登录成功
print(request.COOKIES)
obj = redirect("/index/")
obj.set_cookie("islogin",True) #设置cookie值实现保持状态,注意这里的参数,一个是键,一个是值
obj.set_cookie("haiyan","344",20) #20代表过期时间
obj.set_cookie("username", username)
return obj
else:
return render(request,"login.html")
else:
return render(request,"login.html")
def index(request):
is_login = request.COOKIES.get("islogin",None) #得到cookie,有就得到,没有就得到none
if is_login:
username = request.COOKIES.get("username")
return render(request,"index.html",{"username":username})
else:
return redirect("/login/")
login.html文件内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width">
<title>用户登录</title>
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
<script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<style>
.c1{
margin-top: 100px;
}
.btn{
width: 130px;
}
.c2{
margin-left: 40px;
}
</style>
</head>
<body>
<div>
<div>
<div class="c1 col-md-5 col-md-offset-3">
<form action="/login/" method="post" novalidate>
{% csrf_token %}
<div>
<label for="username" class="col-sm-2 control-label">用户名</label>
<div>
<input type="email" id="username" placeholder="Email" name="username">
</div>
</div>
<div>
<label for="password" class="col-sm-2 control-label">密码</label>
<div>
<input type="password" name="password" id="password"
placeholder="Password">
</div>
</div>
<div>
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">登录</button>
<button type="submit" class="btn btn-success c2">注册</button>
</div>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
index.html文件内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width">
<title>Title</title>
</head>
<body>
<h1>hello{{ username }}</h1>
</body>
</html>
三、session的简单使用
1、设置session值
request.session["session_name"]="admin"
2、获取session值
session_name = request.session("session_name")
3、删除session值
del request.session["session_name"] 删除一组键值对
request.session.flush() 删除一条记录
4、检测是否操作session值
if "session_name" is request.session:
5、用户session的随机字符串
request.session.session_key
# 将所有Session失效日期小于当前日期的数据删除
request.session.clear_expired()
# 检查 用户session的随机字符串 在数据库中是否
request.session.exists("session_key")
# 删除当前用户的所有Session数据
request.session.delete("session_key")
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
6、session流程分析
session会把信息保存在服务端,通常session和cookie配合使用。
(1)session设置
request.session["user_id"]=user.pk
request.session["username"]=user.user
内部实现机制如下:
'''
if request.COOKIE.get("sessionid"): #浏览器能取到sessionid,对其进行更新操作
更新sessionid的值
else:
{"user_id": 1, "username": "wang"}
第一步: 生成随机字符串: vwerascxh24asdasdasdsd
第二步: 在django-sesion表生成一条记录:
session - key vwerascxh24asdasdasdsd
session - data {"user_id": 1, "username": "wang"}
第三步:
obj.set_cookie("sessionid", vwerascxh24asdasdasdsd)
'''
(2)session获取
request.session.get("user_id")
'''
第一步: request.COOKIE.get("sessionid"):vwerascxh24asdasdasdsd
第二步: 在django-sesion表查询一条记录:session-key=vwerascxh24asdasdasdsd
第三步: session-data({"user_id":1,"username":"alex"}).get("user_id")
'''
7、session登录示例
views.py文件内容:
def log_in(request):
if request.method == "POST":
username = request.POST['user']
password = request.POST['pwd']
user = UserInfo.objects.filter(username=username, password=password)
if user:
request.session['is_login'] = 'true' #定义session信息
request.session['username'] = username
return redirect('/backend/') ## 登录成功就将url重定向到后台的url
return render(request, 'login.html')
def backend(request):
print(request.session, "------cookie")
print(request.COOKIES, '-------session')
"""
这里必须用读取字典的get()方法把is_login的value缺省设置为False,当用户访问backend这个url先尝试获取这个浏览器对应的session中的
is_login的值。如果对方登录成功的话,在login里就已经把is_login的值修改为了True,反之这个值就是False的
"""
is_login = request.session.get('is_login', False)
if is_login: # 如果为真,就说明用户是正常登陆的
cookie_content = request.COOKIES
session_content = request.session
username = request.session['username']
return render(request, 'backend.html', locals())
else:
return redirect('/login/')
def log_out(request):
"""
直接通过request.session['is_login']回去返回的时候,如果is_login对应的value值不存在会导致程序异常。所以需要做异常处理
"""
try:
del request.session['is_login'] # 删除is_login对应的value值
#request.session.flush() # 删除django-session表中的对应一行记录
except KeyError:
pass
return redirect('/login/') #重定向回登录页面
login.html文件内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post">
<p>用户名: <input type="text" name="user"></p>
<p>密码: <input type="password" name="pwd"></p>
<p><input type="submit"></p>
</form>
</body>
</html>
backend.html文件内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>hello {{ username }}</h3>
<a href="/logout/">注销</a>
</body>
</html>
四、auth模块
auth_user #保存了用户认证所需要的用户信息
python manage.py createsuperuser #创建超级用户命令,然后根据提示输入相关信息,信息保存在auth_user中
from django.contrib import auth #导入模块
1、authenticate() :验证用户输入的用户名和密码是否相同
提供了用户认证,即验证用户名以及密码是否正确,一般需要username和password两个关键字参数
如果认证信息有效,会返回一个User对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。
2、login(HttpRequest, user):登录
该函数接受一个HttpRequest对象,以及一个认证了的User对象
此函数使用django的session框架给某个已认证的用户附加上session id等信息。
3、logout(request) 注销用户
该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。
4、user对象的 is_authenticated()
要求:
(1)用户登录后才能访问某些页面
(2)如果用户没有登录就访问该页面的话直接跳转登录页面
(3)用户在跳转的登录界面中完成登录后,自动访问跳转到之前访问的地址
def my_view(request):
if not request.user.is_authenticated():
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
五、User对象
User 对象属性:username, password(必填项)password用哈希算法保存到数据库
is_staff : 用户是否拥有网站的管理权限.
is_active : 是否允许用户登录, 设置为``False``,可以不用删除用户来禁止 用户登录
1、is_authenticated()
如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法可以 用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name
2、创建用户:create_user
from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email='')
3、修改密码: set_password()
user = User.objects.get(username='')
user.set_password(password='')
user.save
六、基于auth模块实现用户认证
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),
url(r'^reg/', views.reg),
]
views.py文件内容:
from django.shortcuts import render,redirect
from django.contrib import auth
from django.contrib.auth.models import User
def login(request):
if request.method=="POST":
user=request.POST.get("user")
pwd=request.POST.get("pwd")
print("before", request.user)
user=auth.authenticate(username=user,password=pwd)
if user:
auth.login(request,user) # request.user:当前登录对象
return redirect("/index/")
else:
s = "用户名和密码输入错误"
return render(request, "login.html", {"s": s})
return render(request,"login.html")
def index(request):
if not request.user.username:
return redirect("/login/")
print(request.user)
name=request.user.username
return render(request,"index.html",{"name":name})
def logout(request):
auth.logout(request)
return redirect("/login/")
def reg(request):
if request.method=="POST":
username = request.POST.get("username")
password = request.POST.get("password")
User.objects.create_user(username=username,password=password) #得到用户输入的用户名和密码创建一个新用户
s = "恭喜你注册成功,现在可以登录了"
return redirect("/login/")
return render(request,"reg.html")
login.html文件内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
用户名 <input type="text" name="user">
密码 <input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
index.html文件内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h3>hi {{ name }}</h3>
<a href="/logout/">注销</a>
</body>
</html>
转载于:https://blog.51cto.com/qidian510/2113253