Web Development Tips - comprehensive understanding Cookie

A, Cookie appear

Between the browser and server communication and ultimately, the HTTP protocol, but because the HTTP protocol is stateless, so the server does not know the last time the browser do what kind of operation, so serious impediment to the realization of interactive Web applications.

In response to these problems, Netscape programmers created the Cookie.

Two, Cookie transmission

In the implementation of the server Cookie standards, it is necessary for any HTTP request Set-Cookie HTTP header as part of the response:

Set-Cookie: name=value; expires=Tue, 03-Sep-2019 14:10:21 GMT; path=/; domain=.xxx.com;

Such Cookie browser will be stored and added hair Cookie HTTP request back to the server for each request after:

Cookie: name=value

Cookie value by verifying server, sends a request to the browser determines which user belongs.

Third, the browser Coookie

Browser Cookie mainly consists of the following components:

  • Name: Cookie unique name must be addressed through URL encoding. (The case of the same name will appear coverage)

  • Value: URL encoding must be processed through.

  • Domain (domain): By default, the cookie is valid, you can also set the value in the current field to ensure the effectiveness of its subdomains.

  • Path (path): Cookie specify the circumstances in which the path is valid, the default is the current path.

  • Time to failure (expires): By default, it will be automatically deleted at the end of the browser session Cookie; you can also set the date a GMT format, assign specific deletion date; If the date set for the previous date, then the Cookie will be deleted immediately.

  • Signs of safety (secure): After specifying only allowed Cookie sent to the https protocol.

 

When the browser sends a request, only the names and values ​​added to the Cookie field of the request header is transmitted to the server.

Browser provides a very crappy API to manipulate Cookie:

document.cookie

 

Cookie can be written to the above method, each time only write a string Cookie:

document.cookie = 'a=1; secure; path=/'

 

Cookie may also be read by the process of:

document.cookie
// "a=1"

Since the above method of operation is not very intuitive Cookie, generally functions to simplify Cookie write read, set, and delete operations.

For setting the operation of Cookie, you need the following:

      URL encoding processing on the name and value, i.e. using the encodeURIComponent () JavaScript method;

      requested date expires incoming GMT format, it is easier to deal with ways of writing, such as: the number of seconds set manner;

      Note that only the secure attribute name; every piece of information need to use a semicolon spaces.

function setCookie (key, value, attributes) {
  if (typeof document === 'undefined') {
    return
  }
  attributes = Object.assign({}, {
    path: '/'
  }, attributes)

  let { domain, path, expires, secure } = attributes

  if (typeof expires === 'number') {
    expires = new Date(Date.now() + expires * 1000)
  }
  if (expires instanceof Date) {
    expires = expires.toUTCString()
  } else {
    expires = ''
  }

  key = encodeURIComponent(key)
  value = encodeURIComponent(value)

  let cookieStr = `${key}=${value}`

  if (domain) {
    cookieStr += `; domain=${domain}`
  }

  if (path) {
    cookieStr += `; path=${path}`
  }

  if (expires) {
    cookieStr += `; expires=${expires}`
  }

  if (secure) {
    cookieStr += `; secure`
  }

  return (document.cookie = cookieStr)
}

Cookie read operation should be noted that the names and values ​​of URL decoding process, which is decodeURIComponent () JavaScript method call:

function getCookie (name) {
  if (typeof document === 'undefined') {
    return
  }
  let cookies = []
  let jar = {}
  document.cookie && (cookies = document.cookie.split('; '))

  for (let i = 0, max = cookies.length; i < max; i++) {
    let [key, value] = cookies[i].split('=')
    key = decodeURIComponent(key)
    value = decodeURIComponent(value)
    jar[key] = value
    if (key === name) {
      break
    }
  }

  return name ? jar[name] : jar
}

Finally, a clear way more simple, as long as the expiration date (expires) set the date to the past:

function removeCookie (key) {
  setCookie(key, '', { expires: -1 })
}

After introducing the basic operation of the package Cookie, also need to know in order to limit Cookie browser will not be used maliciously, it defines the size of the disk space occupied by Cookie Cookie and the number under each domain.

In order to bypass the restrictions of the number of single domain name Cookie, developers also created a concept called subcookie, there will not repeat, you can refer to [Advanced JavaScript Programming Chapter 23 p633].

 

Fourth, the service side of the Cookie

Compared browser, the server performs a write operation when the Cookie, Cookie is spliced ​​into the string in response to the Set-Cookie header field; Cookie read operation is executed, parses the HTTP request header field is the Cookie key-value pairs.

The biggest difference with the browser that the server for the safety of Cookie's a lot of trouble

signed

When set signed = true, the server will generate two strip Cookie string Set-Cookie header field in response to:

Set-Cookie: lastTime=2019-03-05T14:31:05.543Z; path=/; httponly
Set-Cookie: lastTime.sig=URXREOYTtMnGm0b7qCYFJ2Db400; path=/; httponly

这里通过再发送一条以.sig为后缀的名称以及对值进行加密的Cookie,来验证该条Cookie是否在传输的过程中被篡改。

httpOnly

服务端Set-Cookie字段中新增httpOnly属性,当服务端在返回的Cookie信息中含有httpOnly字段时,开发者是不能通过JavaScript来操纵该条Cookie字符串的。

这样做的好处主要在于面对XSS(Cross-site scripting)攻击时,黑客无法拿到设置httpOnly字段的Cookie信息。

此时,你会发现localStorage相比较Cookie,在XSS攻击的防御上就略逊一筹了。 sameSite

在介绍这个新属性之前,首先你需要明白:当用户从http://a.com发起http://b.com的请求也会携带上Cookie,而从http://a.com携带过来的Cookie称为第三方Cookie。

虽然第三方Cookie有一些好处,但是给CSRF(Cross-site request forgrey)攻击的机会。

为了从根源上解决CSRF攻击,sameSite属性便闪亮登场了,它的取值有以下几种:

  • strict:浏览器在任何跨域请求中都不会携带Cookie,这样可以有效的防御CSRF攻击,但是对于有多个子域名的网站采用主域名存储用户登录信息的场景,每个子域名都需要用户重新登录,造成用户体验非常的差。

  • lax:相比较strict,它允许从三方网站跳转过来的时候使用Cookie。

 

为了方便大家理解sameSite的实际效果,可以看这个例子:

// a.com 服务端会在访问页面时返回如下Cookie

  cookies.set('foo', 'aaaaa')
  cookies.set('bar', 'bbbbb')
  cookies.set('name', 'cccccc')

  // b.com 服务端会在访问页面时返回如下Cookie
  cookies.set('foo', 'a', { sameSite: 'strict' })
  cookies.set('bar', 'b', { sameSite: 'lax' })
  cookies.set('baz', 'c')

如何现在用户在a.com中点击链接跳转到b.com,它的请求头是这样的:

  Request Headers
  Cookie: bar=b; baz=

五、网站性能优化

Cookie在服务端和浏览器的通信中,主要依靠HTTP的响应头和请求头传输的,所以Cookie会占据一定的带宽。

前面提到浏览器会为每一次HTPP请求自动携带上Cookie信息,但是对于同站内的静态资源,服务器并不需要处理其携带的Cookie,这无形中便浪费了带宽。

在最佳实践中,一般都会将静态资源部署到独立的域名上,从而可以避免无效Cookie的影响。

原文出处

 

Guess you like

Origin www.cnblogs.com/jing-tian/p/11009583.html