zoukankan      html  css  js  c++  java
  • python---django使用cookie和session

    在views中的调用:

    def login(req):
        message=''
        if req.method == "POST":
            user = req.POST.get("username")
            pwd = req.POST.get("password")
    
            count = models.Administrator.objects.filter(username=user,password=pwd).count()
            if count:
                red = redirect("/index.html")
                timeout = datetime.datetime.now()+datetime.timedelta(seconds=3)
                red.set_cookie('username',user,expires=timeout)
          
    rep.set_cookie("info",{"age":10,"name":'fa'})
           return red
         else:
           message
    = "用户名或密码错误"
           return render(req,"login.html",{'msg':message})

    在视图中设置cookie是通过set_cookie方法完成的,而不是请求响应的,并且值是通过字符串返回给请求的。

    补充:

    设置cookie:
    newuser = username.encode('utf-8').decode('latin-1')
    response.set_cookie('uname',newuser)
    
    获取cookie:
    if request.COOKIES.get('uname'):
        context['uname'] = request.COOKIES['uname'].encode('latin-1').decode('utf-8')
    set_cookie不支持中文解决办法
    timeout = datetime.datetime.now()+datetime.timedelta(seconds=3)

    datetime.timedelta主要用来对时间进行运算,如想要获取前一天的时间:

    datetime.datetime.now()-datetime.timedelta(day=1)

    ....可以便捷获取时间值

    获取cookie可以直接使用:

    def index(req):
        # if req.COOKIES
        username = req.COOKIES.get('username',None)
        if username:
            return render(req,"index.html",locals())
        else:
            return redirect("/login.html")

    cookie设置参数了解:

    expires过期时间设置:

    timeout = datetime.datetime.now()+datetime.timedelta(seconds=3)  
    red.set_cookie('username',user,expires=timeout)  #可以直接设置在哪个时间过期  #绝对时间
    red.set_cookie('username',user,expires=10)  #也可以直接设置过期时间:10秒以后  #相对时间

    max_age设置过期时间:

    def test(req):
        rep = HttpResponse("fa")
        if req.COOKIES.get('k1',None):
            print(req.COOKIES.get('k1',None))
        else:
            rep.set_cookie('k1','v1',max_age=10)  #默认是秒数
        return rep

    补充:set_cookie源码:

        def set_cookie(self, key, value='', max_age=None, expires=None, path='/',
                       domain=None, secure=False, httponly=False):
            """
            Sets a cookie.
    
            ``expires`` can be:
            - a string in the correct format,
            - a naive ``datetime.datetime`` object in UTC,
            - an aware ``datetime.datetime`` object in any time zone.
            If it is a ``datetime.datetime`` object then ``max_age`` will be calculated.
            """
            value = force_str(value)
            self.cookies[key] = value
            if expires is not None:
                if isinstance(expires, datetime.datetime):
                    if timezone.is_aware(expires):
                        expires = timezone.make_naive(expires, timezone.utc)
                    delta = expires - expires.utcnow()
                    # Add one second so the date matches exactly (a fraction of
                    # time gets lost between converting to a timedelta and
                    # then the date string).
                    delta = delta + datetime.timedelta(seconds=1)
                    # Just set max_age - the max_age logic will set expires.
                    expires = None
                    max_age = max(0, delta.days * 86400 + delta.seconds)
                else:
                    self.cookies[key]['expires'] = expires
            else:
                self.cookies[key]['expires'] = ''
            if max_age is not None:
                self.cookies[key]['max-age'] = max_age
                # IE requires expires, so set it if hasn't been already.
                if not expires:
                    self.cookies[key]['expires'] = cookie_date(time.time() +
                                                               max_age)
            if path is not None:
                self.cookies[key]['path'] = path
            if domain is not None:
                self.cookies[key]['domain'] = domain
            if secure:
                self.cookies[key]['secure'] = True
            if httponly:
                self.cookies[key]['httponly'] = True

    其中max_age是相对时间,相对获取到cookie的当前时间多少秒后过期:

    而expires包含相对时间和绝对时间,上面介绍的两种相对应

    更多可见:HTTP max-age与Expires的分别

    path设置cookie路径:

            rep.set_cookie('k1','v1',max_age=10,path='/test.html')  #只在该url中生效

    只会在当前路径下/test.html中该cookie才会生效,其他视图下是看不到的

    domain域名:

    默认只在当前域名下存在,可以使用。测试域名可以修改本地hosts文件:

    127.0.0.1 crm.xxx.com
    127.0.0.1 brm.xxx.com

    然后再修改settings文件,设置允许访问的域名:

    ALLOWED_HOSTS = [
        '172.17.164.5',
        'crm.xxx.com',
        'brm.xxx.com',
        'www.py_test.com',    #对于www开头的域名会无法访问(无效),所以最好使用其他域名
       #Invalid HTTP_HOST header: 'www.py_test1.com:8000'. The domain name provided is not valid according to RFC 1034/1035.
    '127.0.0.1', 'localhost' ]
    def test(req):
        rep = HttpResponse("fa")
        if req.COOKIES.get('k1',None):
            print(req.COOKIES.get('k1',None))
        else:
            rep.set_cookie('k1','v1',max_age=10,path='/test.html',domain="xxx.com")  #只在该url中生效
        return rep

    设置为在xxx.com下的域名下都可以进行使用,分别用crm.xxx.com先访问,产生k1:v1键值对,发现在brm.xxx.com中可以正常打印出k1的值,所以域名设置成功

    secure使用:访问时需要证书,对于https访问时,我们需要将secure设置为True才可以正常设置cookie

    httponly安全设置:通过http可以获取cookie,但是使用js是无法获取该键值cookie,

    只是在浏览器中进行了限制,数据包中还是可以获取到该cookie

    签名cookie:

    设置加密cookie(加密,设置签名,可以反解出来):

    rep.set_sgined_cookie("username","dasf")  #dasf:1f163c:rZVvDHeMayCj6kSy4A24UheKptE客户端获取的cookie就不会是明文消息
    rep.set_signed_cookie("username","fawafa")  #fawafa:1f162P:Hl-wrkRxjGeNidsyk0bOGTGqYIE;汉字会转码,也可以反解

    获取加密cookie(解密):

    req.get_signed_cookie("username")

    索引把不敏感的信息放在客户端cookie中,重要的放在session中

    session使用:

    首先需要修改settings文件:

    MIDDLEWARE = [
        ......
    ]
    
    修改为:
    
    MIDDLEWARE_CLASSES = [
        ......
    ]

    然后可以使用:

    print("session:",req.session) #session对象  #req是请求体
    获取数据方法:
    req.session[key]
    设置方法:
    req.session[key]=val
    删除方法:
    del req.session[key]

    session也含有相关的参数(是函数):

    class SessionBase(object):
        """
        Base class for all Session classes.
        """
        TEST_COOKIE_NAME = 'testcookie'
        TEST_COOKIE_VALUE = 'worked'
    
        __not_given = object()
    
        def __init__(self, session_key=None):
            self._session_key = session_key
            self.accessed = False
            self.modified = False
            self.serializer = import_string(settings.SESSION_SERIALIZER)
    
        def __contains__(self, key):
            return key in self._session
    
        def __getitem__(self, key):
            return self._session[key]
    
        def __setitem__(self, key, value):
            self._session[key] = value
            self.modified = True
    
        def __delitem__(self, key):
            del self._session[key]
            self.modified = True
    
        def get(self, key, default=None):
            return self._session.get(key, default)
    
        def pop(self, key, default=__not_given):
            self.modified = self.modified or key in self._session
            args = () if default is self.__not_given else (default,)
            return self._session.pop(key, *args)
    
        def setdefault(self, key, value):
            if key in self._session:
                return self._session[key]
            else:
                self.modified = True
                self._session[key] = value
                return value
    
        def set_test_cookie(self):
            self[self.TEST_COOKIE_NAME] = self.TEST_COOKIE_VALUE
    
        def test_cookie_worked(self):
            return self.get(self.TEST_COOKIE_NAME) == self.TEST_COOKIE_VALUE
    
        def delete_test_cookie(self):
            del self[self.TEST_COOKIE_NAME]
    
        def _hash(self, value):
            key_salt = "django.contrib.sessions" + self.__class__.__name__
            return salted_hmac(key_salt, value).hexdigest()
    
        def encode(self, session_dict):
            "Returns the given session dictionary serialized and encoded as a string."
            serialized = self.serializer().dumps(session_dict)
            hash = self._hash(serialized)
            return base64.b64encode(hash.encode() + b":" + serialized).decode('ascii')
    
        def decode(self, session_data):
            encoded_data = base64.b64decode(force_bytes(session_data))
            try:
                # could produce ValueError if there is no ':'
                hash, serialized = encoded_data.split(b':', 1)
                expected_hash = self._hash(serialized)
                if not constant_time_compare(hash.decode(), expected_hash):
                    raise SuspiciousSession("Session data corrupted")
                else:
                    return self.serializer().loads(serialized)
            except Exception as e:
                # ValueError, SuspiciousOperation, unpickling exceptions. If any of
                # these happen, just return an empty dictionary (an empty session).
                if isinstance(e, SuspiciousOperation):
                    logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
                    logger.warning(force_text(e))
                return {}
    
        def update(self, dict_):
            self._session.update(dict_)
            self.modified = True
    
        def has_key(self, key):
            return key in self._session
    
        def keys(self):
            return self._session.keys()
    
        def values(self):
            return self._session.values()
    
        def items(self):
            return self._session.items()
    
        def iterkeys(self):
            return self._session.iterkeys()
    
        def itervalues(self):
            return self._session.itervalues()
    
        def iteritems(self):
            return self._session.iteritems()
    
        def clear(self):
            # To avoid unnecessary persistent storage accesses, we set up the
            # internals directly (loading data wastes time, since we are going to
            # set it to an empty dict anyway).
            self._session_cache = {}
            self.accessed = True
            self.modified = True
    
        def is_empty(self):
            "Returns True when there is no session_key and the session is empty"
            try:
                return not bool(self._session_key) and not self._session_cache
            except AttributeError:
                return True
    
        def _get_new_session_key(self):
            "Returns session key that isn't being used."
            while True:
                session_key = get_random_string(32, VALID_KEY_CHARS)
                if not self.exists(session_key):
                    break
            return session_key
    
        def _get_or_create_session_key(self):
            if self._session_key is None:
                self._session_key = self._get_new_session_key()
            return self._session_key
    
        def _validate_session_key(self, key):
            """
            Key must be truthy and at least 8 characters long. 8 characters is an
            arbitrary lower bound for some minimal key security.
            """
            return key and len(key) >= 8
    
        def _get_session_key(self):
            return self.__session_key
    
        def _set_session_key(self, value):
            """
            Validate session key on assignment. Invalid values will set to None.
            """
            if self._validate_session_key(value):
                self.__session_key = value
            else:
                self.__session_key = None
    
        session_key = property(_get_session_key)
        _session_key = property(_get_session_key, _set_session_key)
    
        def _get_session(self, no_load=False):
            """
            Lazily loads session from storage (unless "no_load" is True, when only
            an empty dict is stored) and stores it in the current instance.
            """
            self.accessed = True
            try:
                return self._session_cache
            except AttributeError:
                if self.session_key is None or no_load:
                    self._session_cache = {}
                else:
                    self._session_cache = self.load()
            return self._session_cache
    
        _session = property(_get_session)
    
        def get_expiry_age(self, **kwargs):
            """Get the number of seconds until the session expires.
    
            Optionally, this function accepts `modification` and `expiry` keyword
            arguments specifying the modification and expiry of the session.
            """
            try:
                modification = kwargs['modification']
            except KeyError:
                modification = timezone.now()
            # Make the difference between "expiry=None passed in kwargs" and
            # "expiry not passed in kwargs", in order to guarantee not to trigger
            # self.load() when expiry is provided.
            try:
                expiry = kwargs['expiry']
            except KeyError:
                expiry = self.get('_session_expiry')
    
            if not expiry:   # Checks both None and 0 cases
                return settings.SESSION_COOKIE_AGE
            if not isinstance(expiry, datetime):
                return expiry
            delta = expiry - modification
            return delta.days * 86400 + delta.seconds
    
        def get_expiry_date(self, **kwargs):
            """Get session the expiry date (as a datetime object).
    
            Optionally, this function accepts `modification` and `expiry` keyword
            arguments specifying the modification and expiry of the session.
            """
            try:
                modification = kwargs['modification']
            except KeyError:
                modification = timezone.now()
            # Same comment as in get_expiry_age
            try:
                expiry = kwargs['expiry']
            except KeyError:
                expiry = self.get('_session_expiry')
    
            if isinstance(expiry, datetime):
                return expiry
            if not expiry:   # Checks both None and 0 cases
                expiry = settings.SESSION_COOKIE_AGE
            return modification + timedelta(seconds=expiry)
    
        def set_expiry(self, value):
            """
            Sets a custom expiration for the session. ``value`` can be an integer,
            a Python ``datetime`` or ``timedelta`` object or ``None``.
    
            If ``value`` is an integer, the session will expire after that many
            seconds of inactivity. If set to ``0`` then the session will expire on
            browser close.
    
            If ``value`` is a ``datetime`` or ``timedelta`` object, the session
            will expire at that specific future time.
    
            If ``value`` is ``None``, the session uses the global session expiry
            policy.
            """
            if value is None:
                # Remove any custom expiration for this session.
                try:
                    del self['_session_expiry']
                except KeyError:
                    pass
                return
            if isinstance(value, timedelta):
                value = timezone.now() + value
            self['_session_expiry'] = value
    
        def get_expire_at_browser_close(self):
            """
            Returns ``True`` if the session is set to expire when the browser
            closes, and ``False`` if there's an expiry date. Use
            ``get_expiry_date()`` or ``get_expiry_age()`` to find the actual expiry
            date/age, if there is one.
            """
            if self.get('_session_expiry') is None:
                return settings.SESSION_EXPIRE_AT_BROWSER_CLOSE
            return self.get('_session_expiry') == 0
    
        def flush(self):
            """
            Removes the current session data from the database and regenerates the
            key.
            """
            self.clear()
            self.delete()
            self._session_key = None
    
        def cycle_key(self):
            """
            Creates a new session key, while retaining the current session data.
            """
            data = self._session
            key = self.session_key
            self.create()
            self._session_cache = data
            if key:
                self.delete(key)
    
        # Methods that child classes must implement.
    
        def exists(self, session_key):
            """
            Returns True if the given session_key already exists.
            """
            raise NotImplementedError('subclasses of SessionBase must provide an exists() method')
    
        def create(self):
            """
            Creates a new session instance. Guaranteed to create a new object with
            a unique key and will have saved the result once (with empty data)
            before the method returns.
            """
            raise NotImplementedError('subclasses of SessionBase must provide a create() method')
    
        def save(self, must_create=False):
            """
            Saves the session data. If 'must_create' is True, a new session object
            is created (otherwise a CreateError exception is raised). Otherwise,
            save() only updates an existing object and does not create one
            (an UpdateError is raised).
            """
            raise NotImplementedError('subclasses of SessionBase must provide a save() method')
    
        def delete(self, session_key=None):
            """
            Deletes the session data under this key. If the key is None, the
            current session key value is used.
            """
            raise NotImplementedError('subclasses of SessionBase must provide a delete() method')
    
        def load(self):
            """
            Loads the session data and returns a dictionary.
            """
            raise NotImplementedError('subclasses of SessionBase must provide a load() method')
    
        @classmethod
        def clear_expired(cls):
            """
            Remove expired sessions from the session store.
    
            If this operation isn't possible on a given backend, it should raise
            NotImplementedError. If it isn't necessary, because the backend has
            a built-in expiration mechanism, it should be a no-op.
            """
            raise NotImplementedError('This backend does not support clear_expired().')

     补充session全局配置:

    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,默认修改之后才保存(默认
    View Code

     对于用户登录状态,不止cookie,session也可以来完成,设置session的过期时间为7天(或者更长),函数中修改配置

    def login(req):
        ....
        req.session.set_expiry(60*60*24*7)  //将用户信息保存
    }
    {% if req.session.user_info %}
                            <a href="">{{ req.session.user_info.username }}</a>·<a href="">我的博客</a>·<a href="">管理</a>|<a href="/logout.html">退出</a>
                        {% else %}
                            <a href="/login.html">登录</a>|<a href="/register.html">注册</a>
                        {% endif %}
    前端使用
  • 相关阅读:
    asp.net 、C#实现微信企业号OAuth2认证
    node event中 on emit off 的封装
    node
    Express中间件
    旋转的魔方
    通过gulp为requireJs引入的模块添加版本号
    css水平垂直居中(绝对定位居中)
    COLOR 与 COLORREF
    VMware Workstation 安装 vmware tools
    MMIV: starter level 1
  • 原文地址:https://www.cnblogs.com/ssyfj/p/8663781.html
Copyright © 2011-2022 走看看