zoukankan      html  css  js  c++  java
  • 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())

     

     

     

  • 相关阅读:
    Haskell Interactive Development in Emacs
    Access Java API in Groovy Script
    手工设置Eclipse文本编辑器的配色
    Color Theme of Emacs
    Gnucash的投资记录
    Special Forms and Syntax Sugars in Clojure
    Use w3m as Web Browser
    SSE指令集加速之 I420转BGR24
    【图像处理】 增加程序速度的方法
    TBB 入门笔记
  • 原文地址:https://www.cnblogs.com/hantaozi430/p/8489783.html
Copyright © 2011-2022 走看看