Django中Cookie与Session实现用户登录状态保持详解
本文详解Django中利用Cookie和Session保持用户登录状态的方法。Cookie通过浏览器存储键值对实现,Session将数据存于服务端以提高安全性。文章提供了Django中设置、获取、删除Cookie及Session的具体代码示例,包括views.py配置和login.html前端交互,帮助开发者实现安全的用户认证功能。
Django Cookie与Session实现用户登录状态详解
简介
HTTP协议本身是无状态的,这意味着每次请求都是独立的,服务器无法识别用户身份。为了在用户再次访问或浏览其他页面时保留登录状态,避免重复认证,我们可以利用Cookie或Session机制让浏览器记住用户身份。
Cookie与Session说明与实现
Cookie机制与Django实现
Cookie
说明
Cookie是服务器生成并发送给浏览器的一小段数据,通常以键值对形式存在。浏览器会保存这些数据,并在后续访问同一服务器时自动携带Cookie。由于浏览器的同源策略限制,Cookie不会发送给其他域名的服务器,从而保证了数据的隔离性。
Django中实现Cookie
from django.shortcuts import render, redirect
# 设置cookie
"""
key: cookie的名字
value: cookie对应的值
max_age: cookie过期的时间
"""
response.set_cookie(key, value, max_age)
# 为了安全,有时候我们会调用下面的函数来给cookie加盐
response.set_signed_cookie(key,value,salt='加密盐',...)
# 获取cookie
request.COOKIES.get(key)
request.get_signed_cookie(key, salt="加密盐", default=None)
# 删除cookie
reponse.delete_cookie(key)
下面就是具体的代码实现了
views.py
# 编写装饰器检查用户是否登录
def check_login(func):
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
# 假设设置的cookie的key为login,value为yes
if request.get_signed_cookie("login", salt="SSS", default=None) == 'yes':
# 已经登录的用户,则放行
return func(request, *args, **kwargs)
else:
# 没有登录的用户,跳转到登录页面
return redirect(f"/login?next={next_url}")
return inner
# 编写用户登录页面的控制函数
@csrf_exempt
def login(request):
if request.method == "POST":
username = request.POST.get("username")
passwd = request.POST.get("password")
next_url = request.POST.get("next_url")
# 对用户进行验证,假设用户名为:aaa, 密码为123
if username === 'aaa' and passwd == '123':
# 执行其他逻辑操作,例如保存用户信息到数据库等
# print(f'next_url={next_url}')
# 登录成功后跳转,否则直接回到主页面
if next_url and next_url != "/logout/":
response = redirect(next_url)
else:
response = redirect("/index/")
# 若登录成功,则设置cookie,加盐值可自己定义取,这里定义12小时后cookie过期
response.set_signed_cookie("login", 'yes', salt="SSS", max_age=60*60*12)
return response
else:
# 登录失败,则返回失败提示到登录页面
error_msg = '登录验证失败,请重新尝试'
return render(request, "app/login.html", {
'login_error_msg': error_msg,
'next_url': next_url,
})
# 用户刚进入登录页面时,获取到跳转链接,并保存
next_url = request.GET.get("next", '')
return render(request, "app/login.html", {
'next_url': next_url
})
# 登出页面
def logout(request):
rep = redirect("/login/")
# 删除用户浏览器上之前设置的cookie
rep.delete_cookie('login')
return rep
# 给主页添加登录权限认证
@check_login
def index(request):
return render(request, "app/index.html")
从上述代码可以看出,实现逻辑包括:用户首次登录成功时设置Cookie;访问其他页面时验证Cookie有效性;用户登出时删除Cookie。此外,还包含了前端login.html的部分代码用于交互。
<form action="{% url 'login' %}" method="post">
<h1>请使xx账户登录</h1>
<div>
<input id="user" type="text" class="form-control" name="username" placeholder="账户" required="" />
</div>
<div>
<input id="pwd" type="password" class="form-control" name="password" placeholder="密码" required="" />
</div>
<div style="display: none;">
<input id="next" type="text" name="next_url" value="{{ next_url }}" />
</div>
{% if login_error_msg %}
<div id="error-msg">
<span style="color: rgba(255,53,49,0.8); font-family: cursive;">{{ login_error_msg }}</span>
</div>
{% endif %}
<div>
<button type="submit" class="btn btn-default" style="float: initial; margin-left: 0px">登录</button>
</div>
</form>
Session机制与Django实现
Session
Session说明
Session旨在提高用户信息的安全性,将敏感数据存储在服务器端进行验证。尽管Session依赖于Cookie,但其核心机制不同:服务器为每个客户端生成一个唯一的Cookie值(Key),该值作为Session的标识符。
当客户端再次访问服务器时,会将该Cookie发送给服务器。服务器根据Cookie中的值,在Session数据库中查找对应的用户信息。在Django中,可以通过配置setting.py来指定Session存储的数据库类型。
由于Session将用户敏感信息保存在服务器数据库中,相比Cookie直接存储在客户端,具有更高的安全性,不易被窃取或篡改。
Django中Session的实现
# 设置session数据, key是字符串,value可以是任何值
request.session[key] = value
# 获取 session
request.session.get[key]
# 删除 session中的某个数据
del request.session[key]
# 清空session中的所有数据
request.session.delete()
下面就是具体的代码实现了:
首先就是设置保存session的数据库了。这个在setting.py中配置:(注意我这里数据库用的mongodb,并使用了django_mongoengine库;关于这个配置请根据自己使用的数据库进行选择,具体配置可参考官方教程)
SESSION_ENGINE = 'django_mongoengine.sessions'
SESSION_SERIALIZER = 'django_mongoengine.sessions.BSONSerializer'
views.py
# 编写装饰器检查用户是否登录
def check_login(func):
def inner(request, *args, **kwargs):
next_url = request.get_full_path()
# 获取session判断用户是否已登录
if request.session.get('is_login'):
# 已经登录的用户...
return func(request, *args, **kwargs)
else:
# 没有登录的用户,跳转刚到登录页面
return redirect(f"/login?next={next_url}")
return inner
@csrf_exempt
def login(request):
if request.method == "POST":
username = request.POST.get("username")
passwd = request.POST.get("password")
next_url = request.POST.get("next_url")
# 若是有记住密码功能
# remember_sign = request.POST.get("check_remember")
# print(remember_sign)
# 对用户进行验证
if username == 'aaa' and passwd == '123':
# 进行逻辑处理,比如保存用户与密码到数据库
# 若要使用记住密码功能,可保存用户名、密码到session
# request.session['user_info'] = {
# 'username': username,
# 'password': passwd
# }
request.session['is_login'] = True
# 判断是否勾选了记住密码的复选框
# if remember_sign == 'on':
# request.session['is_remember'] = True
# else:
# request.session['is_remember'] = False
# print(f'next_url={next_url}')
if next_url and next_url != "/logout/":
response = redirect(next_url)
else:
response = redirect("/index/")
return response
else:
error_msg = '登录验证失败,请重新尝试'
return render(request, "app/login.html", {
'login_error_msg': error_msg,
'next_url': next_url,
})
next_url = request.GET.get("next", '')
# 检查是否勾选了记住密码功能
# password, check_value = '', ''
# user_session = request.session.get('user_info', {})
# username = user_session.get('username', '')
# print(user_session)
#if request.session.get('is_remember'):
# password = user_session.get('password', '')
# check_value = 'checked'
# print(username, password)
return render(request, "app/login.html", {
'next_url': next_url,
# 'user': username,
# 'password': password,
# 'check_value': check_value
})
def logout(request):
rep = redirect("/login/")
# request.session.delete()
# 登出,则删除掉session中的某条数据
if 'is_login' in request.session:
del request.session['is_login']
return rep
@check_login
def index(request):
return render(request, "autotest/index.html")
另附login.html部分代码:
<form action="{% url 'login' %}" method="post">
<h1>请使xxx账户登录</h1>
<div>
<input id="user" type="text" class="form-control" name="username" placeholder="用户" required="" value="{{ user }}" />
</div>
<div>
<input id="pwd" type="password" class="form-control" name="password" placeholder="密码" required="" value="{{ password }}" />
</div>
<div style="display: none;">
<input id="next" type="text" name="next_url" value="{{ next_url }}" />
</div>
{% if login_error_msg %}
<div id="error-msg">
<span style="color: rgba(255,53,49,0.8); font-family: cursive;">{{ login_error_msg }}</span>
</div>
{% endif %}
// 若设置了记住密码功能
// <div style="float: left">
// <input id="rmb-me" type="checkbox" name="check_remember" {{ check_value }}/>记住密码
// </div>
<div>
<button type="submit" class="btn btn-default" style="float: initial; margin-right: 60px">登录</button>
</div>
</form>
总体而言,Session同样利用了Cookie,通过Cookie中唯一生成的Value值,在后端数据库的Session表中查找对应的数据。Session能够保存更多的用户信息,且这些信息不易被暴露,从而提升了安全性。
总结
总结
Session和Cookie都能实现记住用户登录状态的功能,如果为了安全起见,还是使用Session更合适
以上这篇Django Session和Cookie分别实现记住用户登录状态操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













