def set_cookie(self, name, value, expires=None, max_age=None, domain=None, path=None, secure=True, http_only=True): """Set a response cookie. Note: This method can be called multiple times to add one or more cookies to the response. See Also: To learn more about setting cookies, see :ref:`Setting Cookies <setting-cookies>`. The parameters listed below correspond to those defined in `RFC 6265`_. Args: name (str): Cookie name value (str): Cookie value Keyword Args: expires (datetime): Specifies when the cookie should expire. By default, cookies expire when the user agent exits. (See also: RFC 6265, Section 4.1.2.1) max_age (int): Defines the lifetime of the cookie in seconds. By default, cookies expire when the user agent exits. If both `max_age` and `expires` are set, the latter is ignored by the user agent. Note: Coercion to ``int`` is attempted if provided with ``float`` or ``str``. (See also: RFC 6265, Section 4.1.2.2) domain (str): Restricts the cookie to a specific domain and any subdomains of that domain. By default, the user agent will return the cookie only to the origin server. When overriding this default behavior, the specified domain must include the origin server. Otherwise, the user agent will reject the cookie. (See also: RFC 6265, Section 4.1.2.3) path (str): Scopes the cookie to the given path plus any subdirectories under that path (the "/" character is interpreted as a directory separator). If the cookie does not specify a path, the user agent defaults to the path component of the requested URI. Warning: User agent interfaces do not always isolate cookies by path, and so this should not be considered an effective security measure. (See also: RFC 6265, Section 4.1.2.4) secure (bool): Direct the client to only return the cookie in subsequent requests if they are made over HTTPS (default: ``True``). This prevents attackers from reading sensitive cookie data. Warning: For the `secure` cookie attribute to be effective, your application will need to enforce HTTPS. (See also: RFC 6265, Section 4.1.2.5) http_only (bool): Direct the client to only transfer the cookie with unscripted HTTP requests (default: ``True``). This is intended to mitigate some forms of cross-site scripting. (See also: RFC 6265, Section 4.1.2.6) Raises: KeyError: `name` is not a valid cookie name. ValueError: `value` is not a valid cookie value. .. _RFC 6265: http://tools.ietf.org/html/rfc6265 """ if not is_ascii_encodable(name): raise KeyError('"name" is not ascii encodable') if not is_ascii_encodable(value): raise ValueError('"value" is not ascii encodable') if PY2: name = str(name) value = str(value) if self._cookies is None: self._cookies = SimpleCookie() try: self._cookies[name] = value except CookieError as e: # pragma: no cover # NOTE(tbug): we raise a KeyError here, to avoid leaking # the CookieError to the user. SimpleCookie (well, BaseCookie) # only throws CookieError on issues with the cookie key raise KeyError(str(e)) if expires: # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT # NOTE(tbug): we never actually need to # know that GMT is named GMT when formatting cookies. # It is a function call less to just write "GMT" in the fmt string: fmt = "%a, %d %b %Y %H:%M:%S GMT" if expires.tzinfo is None: # naive self._cookies[name]["expires"] = expires.strftime(fmt) else: # aware gmt_expires = expires.astimezone(GMT_TIMEZONE) self._cookies[name]["expires"] = gmt_expires.strftime(fmt) if max_age: # RFC 6265 section 5.2.2 says about the max-age value: # "If the remainder of attribute-value contains a non-DIGIT # character, ignore the cookie-av." # That is, RFC-compliant response parsers will ignore the max-age # attribute if the value contains a dot, as in floating point # numbers. Therefore, attempt to convert the value to an integer. self._cookies[name]["max-age"] = int(max_age) if domain: self._cookies[name]["domain"] = domain if path: self._cookies[name]["path"] = path if secure: self._cookies[name]["secure"] = secure if http_only: self._cookies[name]["httponly"] = http_only
def set_cookie(self, name, value, expires=None, max_age=None, domain=None, path=None, secure=True, http_only=True): """Set a response cookie. Note: This method can be called multiple times to add one or more cookies to the response. See Also: To learn more about setting cookies, see :ref:`Setting Cookies <setting-cookies>`. The parameters listed below correspond to those defined in `RFC 6265`_. Args: name (str): Cookie name value (str): Cookie value expires (datetime): Specifies when the cookie should expire. By default, cookies expire when the user agent exits. max_age (int): Defines the lifetime of the cookie in seconds. After the specified number of seconds elapse, the client should discard the cookie. domain (str): Specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot. A value of 0 means the cookie should be discarded immediately. path (str): Specifies the subset of URLs to which this cookie applies. secure (bool): Direct the client to use only secure means to contact the origin server whenever it sends back this cookie (default: ``True``). Warning: You will also need to enforce HTTPS for the cookies to be transfered securely. http_only (bool): Direct the client to only transfer the cookie with unscripted HTTP requests (default: ``True``). This is intended to mitigate some forms of cross-site scripting. Raises: KeyError: `name` is not a valid cookie name. ValueError: `value` is not a valid cookie value. .. _RFC 6265: http://tools.ietf.org/html/rfc6265 """ if not is_ascii_encodable(name): raise KeyError('"name" is not ascii encodable') if not is_ascii_encodable(value): raise ValueError('"value" is not ascii encodable') if PY2: # pragma: no cover name = str(name) value = str(value) if self._cookies is None: self._cookies = SimpleCookie() try: self._cookies[name] = value except CookieError as e: # pragma: no cover # NOTE(tbug): we raise a KeyError here, to avoid leaking # the CookieError to the user. SimpleCookie (well, BaseCookie) # only throws CookieError on issues with the cookie key raise KeyError(str(e)) if expires: # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT # NOTE(tbug): we never actually need to # know that GMT is named GMT when formatting cookies. # It is a function call less to just write "GMT" in the fmt string: fmt = "%a, %d %b %Y %H:%M:%S GMT" if expires.tzinfo is None: # naive self._cookies[name]["expires"] = expires.strftime(fmt) else: # aware gmt_expires = expires.astimezone(GMT_TIMEZONE) self._cookies[name]["expires"] = gmt_expires.strftime(fmt) if max_age: self._cookies[name]["max-age"] = max_age if domain: self._cookies[name]["domain"] = domain if path: self._cookies[name]["path"] = path if secure: self._cookies[name]["secure"] = secure if http_only: self._cookies[name]["httponly"] = http_only
def set_cookie(self, name, value, expires=None, max_age=None, domain=None, path=None, secure=True, http_only=True): """Set a response cookie. Note: :meth:`~.set_cookie` is capable of setting multiple cookies with specified cookie properties on the same request. Currently :meth:`~.set_header` and :meth:`~.append_header` are not capable of this. Args: name (str): Cookie name value (str): Cookie value expires (datetime): Defines when the cookie should expire. the default is to expire when the browser is closed. max_age (int): The Max-Age attribute defines the lifetime of the cookie, in seconds. The delta-seconds value is a decimal non- negative integer. After delta-seconds seconds elapse, the client should discard the cookie. domain (str): The Domain attribute specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot. A value of 0 means the cookie should be discarded immediately. path (str): The Path attribute specifies the subset of URLs to which this cookie applies. secure (bool) (default: True): The Secure attribute directs the user agent to use only secure means to contact the origin server whenever it sends back this cookie. Warning: You will also need to enforce HTTPS for the cookies to be transfered securely. http_only (bool) (default: True): The attribute http_only specifies that the cookie is only transferred in HTTP requests, and is not accessible through JavaScript. This is intended to mitigate some forms of cross-site scripting. Note: Kwargs and their valid values are all specified in http://tools.ietf.org/html/rfc6265 See Also: :ref:`Setting Cookies <setting-cookies>` Raises: KeyError if ``name`` is not a valid cookie name. """ if not is_ascii_encodable(name): raise KeyError('"name" is not ascii encodable') if not is_ascii_encodable(value): raise ValueError('"value" is not ascii encodable') if six.PY2: # pragma: no cover name = str(name) value = str(value) if self._cookies is None: self._cookies = SimpleCookie() try: self._cookies[name] = value except CookieError as e: # pragma: no cover # NOTE(tbug): we raise a KeyError here, to avoid leaking # the CookieError to the user. SimpleCookie (well, BaseCookie) # only throws CookieError on issues with the cookie key raise KeyError(str(e)) if expires: # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT # NOTE(tbug): we never actually need to # know that GMT is named GMT when formatting cookies. # It is a function call less to just write "GMT" in the fmt string: fmt = "%a, %d %b %Y %H:%M:%S GMT" if expires.tzinfo is None: # naive self._cookies[name]["expires"] = expires.strftime(fmt) else: # aware gmt_expires = expires.astimezone(GMT_TIMEZONE) self._cookies[name]["expires"] = gmt_expires.strftime(fmt) if max_age: self._cookies[name]["max-age"] = max_age if domain: self._cookies[name]["domain"] = domain if path: self._cookies[name]["path"] = path if secure: self._cookies[name]["secure"] = secure if http_only: self._cookies[name]["httponly"] = http_only
def set_cookie(self, name, value, expires=None, max_age=None, domain=None, path=None, secure=True, http_only=True): """Set a response cookie. Note: This method can be called multiple times to add one or more cookies to the response. See Also: To learn more about setting cookies, see :ref:`Setting Cookies <setting-cookies>`. The parameters listed below correspond to those defined in `RFC 6265`_. Args: name (str): Cookie name value (str): Cookie value expires (datetime): Specifies when the cookie should expire. By default, cookies expire when the user agent exits. max_age (int): Defines the lifetime of the cookie in seconds. After the specified number of seconds elapse, the client should discard the cookie. Coercion to `int` is attempted if provided with `float` or `str`. domain (str): Specifies the domain for which the cookie is valid. An explicitly specified domain must always start with a dot. A value of 0 means the cookie should be discarded immediately. path (str): Specifies the subset of URLs to which this cookie applies. secure (bool): Direct the client to only return the cookie in subsequent requests if they are made over HTTPS (default: ``True``). This prevents attackers from reading sensitive cookie data. Note that for the `secure` cookie attribute to be effective, your application will need to enforce HTTPS. See also: `RFC 6265, Section 4.1.2.5`_. http_only (bool): Direct the client to only transfer the cookie with unscripted HTTP requests (default: ``True``). This is intended to mitigate some forms of cross-site scripting. Raises: KeyError: `name` is not a valid cookie name. ValueError: `value` is not a valid cookie value. .. _RFC 6265: http://tools.ietf.org/html/rfc6265 .. _RFC 6265, Section 4.1.2.5: https://tools.ietf.org/html/rfc6265#section-4.1.2.5 """ if not is_ascii_encodable(name): raise KeyError('"name" is not ascii encodable') if not is_ascii_encodable(value): raise ValueError('"value" is not ascii encodable') if PY2: name = str(name) value = str(value) if self._cookies is None: self._cookies = SimpleCookie() try: self._cookies[name] = value except CookieError as e: # pragma: no cover # NOTE(tbug): we raise a KeyError here, to avoid leaking # the CookieError to the user. SimpleCookie (well, BaseCookie) # only throws CookieError on issues with the cookie key raise KeyError(str(e)) if expires: # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT # NOTE(tbug): we never actually need to # know that GMT is named GMT when formatting cookies. # It is a function call less to just write "GMT" in the fmt string: fmt = '%a, %d %b %Y %H:%M:%S GMT' if expires.tzinfo is None: # naive self._cookies[name]['expires'] = expires.strftime(fmt) else: # aware gmt_expires = expires.astimezone(GMT_TIMEZONE) self._cookies[name]['expires'] = gmt_expires.strftime(fmt) if max_age: # RFC 6265 section 5.2.2 says about the max-age value: # "If the remainder of attribute-value contains a non-DIGIT # character, ignore the cookie-av." # That is, RFC-compliant response parsers will ignore the max-age # attribute if the value contains a dot, as in floating point # numbers. Therefore, attempt to convert the value to an integer. self._cookies[name]['max-age'] = int(max_age) if domain: self._cookies[name]['domain'] = domain if path: self._cookies[name]['path'] = path if secure: self._cookies[name]['secure'] = secure if http_only: self._cookies[name]['httponly'] = http_only
def set_cookie(self, name, value, expires=None, max_age=None, domain=None, path=None, secure=None, http_only=True): """Set a response cookie. Note: This method can be called multiple times to add one or more cookies to the response. See Also: To learn more about setting cookies, see :ref:`Setting Cookies <setting-cookies>`. The parameters listed below correspond to those defined in `RFC 6265`_. Args: name (str): Cookie name value (str): Cookie value Keyword Args: expires (datetime): Specifies when the cookie should expire. By default, cookies expire when the user agent exits. (See also: RFC 6265, Section 4.1.2.1) max_age (int): Defines the lifetime of the cookie in seconds. By default, cookies expire when the user agent exits. If both `max_age` and `expires` are set, the latter is ignored by the user agent. Note: Coercion to ``int`` is attempted if provided with ``float`` or ``str``. (See also: RFC 6265, Section 4.1.2.2) domain (str): Restricts the cookie to a specific domain and any subdomains of that domain. By default, the user agent will return the cookie only to the origin server. When overriding this default behavior, the specified domain must include the origin server. Otherwise, the user agent will reject the cookie. (See also: RFC 6265, Section 4.1.2.3) path (str): Scopes the cookie to the given path plus any subdirectories under that path (the "/" character is interpreted as a directory separator). If the cookie does not specify a path, the user agent defaults to the path component of the requested URI. Warning: User agent interfaces do not always isolate cookies by path, and so this should not be considered an effective security measure. (See also: RFC 6265, Section 4.1.2.4) secure (bool): Direct the client to only return the cookie in subsequent requests if they are made over HTTPS (default: ``True``). This prevents attackers from reading sensitive cookie data. Note: The default value for this argument is normally ``True``, but can be modified by setting :py:attr:`~.ResponseOptions.secure_cookies_by_default` via :any:`API.resp_options`. Warning: For the `secure` cookie attribute to be effective, your application will need to enforce HTTPS. (See also: RFC 6265, Section 4.1.2.5) http_only (bool): Direct the client to only transfer the cookie with unscripted HTTP requests (default: ``True``). This is intended to mitigate some forms of cross-site scripting. (See also: RFC 6265, Section 4.1.2.6) Raises: KeyError: `name` is not a valid cookie name. ValueError: `value` is not a valid cookie value. .. _RFC 6265: http://tools.ietf.org/html/rfc6265 """ if not is_ascii_encodable(name): raise KeyError('"name" is not ascii encodable') if not is_ascii_encodable(value): raise ValueError('"value" is not ascii encodable') name = str(name) value = str(value) if self._cookies is None: self._cookies = SimpleCookie() try: self._cookies[name] = value except CookieError as e: # pragma: no cover # NOTE(tbug): we raise a KeyError here, to avoid leaking # the CookieError to the user. SimpleCookie (well, BaseCookie) # only throws CookieError on issues with the cookie key raise KeyError(str(e)) if expires: # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT # NOTE(tbug): we never actually need to # know that GMT is named GMT when formatting cookies. # It is a function call less to just write "GMT" in the fmt string: fmt = '%a, %d %b %Y %H:%M:%S GMT' if expires.tzinfo is None: # naive self._cookies[name]['expires'] = expires.strftime(fmt) else: # aware gmt_expires = expires.astimezone(GMT_TIMEZONE) self._cookies[name]['expires'] = gmt_expires.strftime(fmt) if max_age: # RFC 6265 section 5.2.2 says about the max-age value: # "If the remainder of attribute-value contains a non-DIGIT # character, ignore the cookie-av." # That is, RFC-compliant response parsers will ignore the max-age # attribute if the value contains a dot, as in floating point # numbers. Therefore, attempt to convert the value to an integer. self._cookies[name]['max-age'] = int(max_age) if domain: self._cookies[name]['domain'] = domain if path: self._cookies[name]['path'] = path if secure is None: is_secure = self.options.secure_cookies_by_default else: is_secure = secure if is_secure: self._cookies[name]['secure'] = True if http_only: self._cookies[name]['httponly'] = http_only
def set_cookie( self, name, value, expires=None, max_age=None, domain=None, path=None, secure=None, http_only=True, same_site=None, ): """Set a response cookie. Note: This method can be called multiple times to add one or more cookies to the response. See Also: To learn more about setting cookies, see :ref:`Setting Cookies <setting-cookies>`. The parameters listed below correspond to those defined in `RFC 6265`_. Args: name (str): Cookie name value (str): Cookie value Keyword Args: expires (datetime): Specifies when the cookie should expire. By default, cookies expire when the user agent exits. (See also: RFC 6265, Section 4.1.2.1) max_age (int): Defines the lifetime of the cookie in seconds. By default, cookies expire when the user agent exits. If both `max_age` and `expires` are set, the latter is ignored by the user agent. Note: Coercion to ``int`` is attempted if provided with ``float`` or ``str``. (See also: RFC 6265, Section 4.1.2.2) domain (str): Restricts the cookie to a specific domain and any subdomains of that domain. By default, the user agent will return the cookie only to the origin server. When overriding this default behavior, the specified domain must include the origin server. Otherwise, the user agent will reject the cookie. Note: Cookies do not provide isolation by port, so the domain should not provide one. (See also: RFC 6265, Section 8.5) (See also: RFC 6265, Section 4.1.2.3) path (str): Scopes the cookie to the given path plus any subdirectories under that path (the "/" character is interpreted as a directory separator). If the cookie does not specify a path, the user agent defaults to the path component of the requested URI. Warning: User agent interfaces do not always isolate cookies by path, and so this should not be considered an effective security measure. (See also: RFC 6265, Section 4.1.2.4) secure (bool): Direct the client to only return the cookie in subsequent requests if they are made over HTTPS (default: ``True``). This prevents attackers from reading sensitive cookie data. Note: The default value for this argument is normally ``True``, but can be modified by setting :py:attr:`~.ResponseOptions.secure_cookies_by_default` via :any:`App.resp_options`. Warning: For the `secure` cookie attribute to be effective, your application will need to enforce HTTPS. (See also: RFC 6265, Section 4.1.2.5) http_only (bool): The HttpOnly attribute limits the scope of the cookie to HTTP requests. In particular, the attribute instructs the user agent to omit the cookie when providing access to cookies via "non-HTTP" APIs. This is intended to mitigate some forms of cross-site scripting. (default: ``True``) Note: HttpOnly cookies are not visible to javascript scripts in the browser. They are automatically sent to the server on javascript ``XMLHttpRequest`` or ``Fetch`` requests. (See also: RFC 6265, Section 4.1.2.6) same_site (str): Helps protect against CSRF attacks by restricting when a cookie will be attached to the request by the user agent. When set to ``'Strict'``, the cookie will only be sent along with "same-site" requests. If the value is ``'Lax'``, the cookie will be sent with same-site requests, and with "cross-site" top-level navigations. If the value is ``'None'``, the cookie will be sent with same-site and cross-site requests. Finally, when this attribute is not set on the cookie, the attribute will be treated as if it had been set to ``'None'``. (See also: `Same-Site RFC Draft`_) Raises: KeyError: `name` is not a valid cookie name. ValueError: `value` is not a valid cookie value. .. _RFC 6265: http://tools.ietf.org/html/rfc6265 .. _Same-Site RFC Draft: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7 """ if not is_ascii_encodable(name): raise KeyError('name is not ascii encodable') if not is_ascii_encodable(value): raise ValueError('value is not ascii encodable') value = str(value) if self._cookies is None: self._cookies = http_cookies.SimpleCookie() try: self._cookies[name] = value except http_cookies.CookieError as e: # pragma: no cover # NOTE(tbug): we raise a KeyError here, to avoid leaking # the CookieError to the user. SimpleCookie (well, BaseCookie) # only throws CookieError on issues with the cookie key raise KeyError(str(e)) if expires: # set Expires on cookie. Format is Wdy, DD Mon YYYY HH:MM:SS GMT # NOTE(tbug): we never actually need to # know that GMT is named GMT when formatting cookies. # It is a function call less to just write "GMT" in the fmt string: fmt = '%a, %d %b %Y %H:%M:%S GMT' if expires.tzinfo is None: # naive self._cookies[name]['expires'] = expires.strftime(fmt) else: # aware gmt_expires = expires.astimezone(GMT_TIMEZONE) self._cookies[name]['expires'] = gmt_expires.strftime(fmt) if max_age: # RFC 6265 section 5.2.2 says about the max-age value: # "If the remainder of attribute-value contains a non-DIGIT # character, ignore the cookie-av." # That is, RFC-compliant response parsers will ignore the max-age # attribute if the value contains a dot, as in floating point # numbers. Therefore, attempt to convert the value to an integer. self._cookies[name]['max-age'] = int(max_age) if domain: self._cookies[name]['domain'] = domain if path: self._cookies[name]['path'] = path is_secure = self.options.secure_cookies_by_default if secure is None else secure if is_secure: self._cookies[name]['secure'] = True if http_only: self._cookies[name]['httponly'] = http_only # PERF(kgriffs): Morsel.__setitem__() will lowercase this anyway, # so we can just pass this in and when __setitem__() calls # lower() it will be very slightly faster. if same_site: same_site = same_site.lower() if same_site not in _RESERVED_SAMESITE_VALUES: raise ValueError( "same_site must be set to either 'lax', 'strict', or 'none'" ) self._cookies[name]['samesite'] = same_site.capitalize()