Django实现cookie&session以及认证系统

COOKIE&SESSION

知识储备

  由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞生。

  cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

  cookie虽然在一定程度上解决了“保持状态”的需求,但是由于cookie本身最大支持4096字节,以及cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是session。

  问题来了,基于http协议的无状态特征,服务器根本就不知道访问者是“谁”。那么上述的cookie就起到桥接的作用。

  我们可以给每个客户端的cookie分配一个唯一的id,这样用户在访问时,通过cookie,服务器就知道来的人是“谁”。然后我们再根据不同的cookie的id,在服务器上保存一段时间的私密资料,如“账号密码”等等。

  总结而言:cookie弥补了http无状态的不足,让服务器知道来的人是“谁”;但是cookie以文本的形式保存在本地,自身安全性较差;所以我们就通过cookie识别不同的用户,对应的在session里保存私密的信息以及超过4096字节的文本

Django实现COOKIE

设置cookie

obj = HttpResponse(...) 或 obj= render(request, ...) 或 obj= redirect()
obj.set_cookie(key,value,...)
obj.set_signed_cookie(key,value,salt='加密盐',...)

获取cookie

request.COOKIES.get('key')
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

删除cookie

response.delete_cookie("cookie_key",path="/",domain=name)

参数

key,                 键
value='',            值
max_age=None,        超长时间
expires=None,        超长时间
path='/',           Cookie生效的路径,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
domain=None,         Cookie生效的域名你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读www.example.com 、 www2.example.com 
和an.other.sub.domain.example.com 。
如果该参数设置为 None ,cookie只能由设置它的站点读取。

secure=False,        如果设置为 True ,浏览器将通过HTTPS来回传cookie。
httponly=False       只能http协议传输,无法被JavaScript获取
                                         (不是绝对,底层抓包可以获取到也可以被覆盖
$.cookie("key", value,{ path: '/' })
jquery操作cookie

Django实现SESSION

设置Session

request.session['key']='value'
'''
实际进行的操作:
    1.  检查请求是否有sessionid,且是否存在与数据库,存在则对session_data进行更新
    2. 若不等,则创建随机字符串
    3. set_cookie('sessionid','随机字符串')
    4. 在session表中添加记录
                  session-key          session-data
                    随机字符串          {"key":"value"}-------------进行处理后的
'''

获取Session

session_name=request.session['key']
'''
实际进行了哪些操作:
    1. 取随机字符串request.COOKIE.get('sessionid')
    2. 在session表中进行过滤:
        obj=django-session.objects.filter(session-key=random_str).first()
        obj.session-data.get("user")

'''

其他

#删除Sessions值
del request.session["session_name"]
#检测是否操作session值
if "session_name" is request.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,默认修改之后才保存(默认
数据库配置(配置)
a. 配置 settings.py
  
    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,默认修改之后才保存
缓存配置
a. 配置 settings.py
  
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()         
    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,默认修改之后才保存
文件配置
def login_session(request):
    if request.method=='POST':
        user=request.POST.get('user')
        pwd=request.POST.get('pwd')
        ret=UserInfo.objects.filter(name=user,pwd=pwd)
        if ret:
            request.session['user']=user
            return redirect('/index_session/')
    return render(request,'login.html')

def index_session(request):
    user=request.session.get('user')
    if not user:
        return redirect('/login_session/')
    return render(request,'index.html',locals())
View Code

Django的用户认证

#先settings配置用户表
AUTH_USER_MODEL="blog.UserInfo"

auth

利用auth模块中的一些方法来进行认证
from django.contrib import auth

authenticate()

提供了用户认证,即验证用户名以及密码是否正确,一般需要username  password两个关键字参数

如果认证信息有效,会返回一个  User  对象。authenticate()会在User 对象上设置一个属性标识那种认证后端认证了该用户,且该信息在后面的登录过程中是需要的。当我们试图登陆一个从数据库中直接取出来不经过authenticate()的User对象会报错的

user = authenticate(username='someone',password='somepassword')

login(HttpRequest, user)

该函数接受一个HttpRequest对象,以及一个认证了的User对象

此函数使用django的session框架给某个已认证的用户附加上session id等信息。

login(request, user)

logout(request) 

 该函数接受一个HttpRequest对象,无返回值。当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

logout(request)

User对象

User 对象属性:

username, password(必填项)password用哈希算法保存到数据库

is_staff : 用户是否拥有网站的管理权限.

is_active : 是否允许用户登录, 设置为``False``,可以不用删除用户来禁止 用户登录

is_authenticated()

如果是真正的 User 对象,返回值恒为 True 。 用于检查用户是否已经通过了认证。
通过认证并不意味着用户拥有任何权限,甚至也不检查该用户是否处于激活状态,这只是表明用户成功的通过了认证。 这个方法很重要, 在后台用request.user.is_authenticated()判断用户是否已经登录,如果true则可以向前台展示request.user.name

if not request.user.is_authenticated():
    return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))

django自带用于此种情况的装饰器:login_requierd()

from django.contrib.auth.decorators import login_required
      
@login_required
def my_view(request):

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' (这个值可以在settings文件中通过LOGIN_URL进行修改)。并传递  当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

创建用户

from django.contrib.auth.models import User
user = User.objects.create_user(username='',password='',email=''

修改密码set_password()

user = User.objects.get(username='')
user.set_password(password='')
user.save

check_password(passwd)

用户需要修改密码的时候 首先要让他输入原来的密码 ,如果给定的字符串通过了密码检查,返回 True

 基于auth认证实现登录:

def login(request):
    '''
    登录验证
    :param request:
    :return:
    '''
    if request.method=='POST':
        username=request.POST.get('username')
        pwd=request.POST.get('pwd')
        input_valid_code=request.POST.get('valid_code')
        valid_code=request.session.get('valid_code')
        login_response={'user':None,'error_msg':''}
        #进行验证码的比较
        if valid_code.upper()==input_valid_code.upper():
            user=auth.authenticate(username=username,password=pwd)
            if user:
                auth.login(request,user)
                login_response['user']=user.username
            else:
                login_response['error_msg']='用户名或密码错误!'
        else:
            login_response['error_msg']='验证码错误!'
        import json
        return HttpResponse(json.dumps(login_response))
    return render(request,'login.html',locals())

 

 

 

原文地址:https://www.cnblogs.com/hantaozi430/p/8489783.html