cookies.asciidoc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. [[cookies]]
  2. == Using cookies
  3. Cookies are a mechanism allowing applications to maintain
  4. state on top of the stateless HTTP protocol.
  5. Cookies are a name/value store where the names and values are
  6. stored in plain text. They expire either after a delay
  7. or when the browser closes. They can be configured on a
  8. specific domain name or path, and restricted to secure
  9. resources (sent or downloaded over HTTPS), or restricted
  10. to the server (disallowing access from client-side scripts).
  11. Cookie names are de facto case sensitive.
  12. Cookies are stored client-side and sent with every subsequent
  13. request that matches the domain and path for which they were
  14. stored, until they expire. This can create a non-negligible
  15. cost.
  16. Cookies should not be considered secure. They are stored on
  17. the user's computer in plain text, and can be read by any
  18. program. They can also be read by proxies when using clear
  19. connections. Always validate the value before using it,
  20. and never store any sensitive information inside it.
  21. Cookies set by the server are only available in requests
  22. following the client reception of the response containing
  23. them.
  24. Cookies may be sent repeatedly. This is often useful to
  25. update the expiration time and avoid losing a cookie.
  26. === Setting cookies
  27. By default cookies are defined for the duration of the session:
  28. [source,erlang]
  29. ----
  30. SessionID = generate_session_id(),
  31. Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, Req0).
  32. ----
  33. They can also be set for a duration in seconds:
  34. [source,erlang]
  35. ----
  36. SessionID = generate_session_id(),
  37. Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, Req0,
  38. #{max_age => 3600}).
  39. ----
  40. To delete cookies, set `max_age` to 0:
  41. [source,erlang]
  42. ----
  43. SessionID = generate_session_id(),
  44. Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, Req0,
  45. #{max_age => 0}).
  46. ----
  47. To restrict cookies to a specific domain and path, the options
  48. of the same name can be used:
  49. [source,erlang]
  50. ----
  51. Req = cowboy_req:set_resp_cookie(<<"inaccount">>, <<"1">>, Req0,
  52. #{domain => "my.example.org", path => "/account"}).
  53. ----
  54. Cookies will be sent with requests to this domain and all
  55. its subdomains, and to resources on this path or deeper
  56. in the path hierarchy.
  57. To restrict cookies to secure channels (typically resources
  58. available over HTTPS):
  59. [source,erlang]
  60. ----
  61. SessionID = generate_session_id(),
  62. Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, Req0,
  63. #{secure => true}).
  64. ----
  65. To prevent client-side scripts from accessing a cookie:
  66. [source,erlang]
  67. ----
  68. SessionID = generate_session_id(),
  69. Req = cowboy_req:set_resp_cookie(<<"sessionid">>, SessionID, Req0,
  70. #{http_only => true}).
  71. ----
  72. Cookies may also be set client-side, for example using
  73. Javascript.
  74. === Reading cookies
  75. The client only ever sends back the cookie name and value.
  76. All other options that can be set are never sent back.
  77. Cowboy provides two functions for reading cookies. Both
  78. involve parsing the cookie header(s) and so should not
  79. be called repeatedly.
  80. You can get all cookies as a key/value list:
  81. [source,erlang]
  82. Cookies = cowboy_req:parse_cookies(Req),
  83. {_, Lang} = lists:keyfind(<<"lang">>, 1, Cookies).
  84. Or you can perform a match against cookies and retrieve
  85. only the ones you need, while at the same time doing
  86. any required post processing using xref:constraints[constraints].
  87. This function returns a map:
  88. [source,erlang]
  89. #{id := ID, lang := Lang} = cowboy_req:match_cookies([id, lang], Req).
  90. You can use constraints to validate the values while matching
  91. them. The following snippet will crash if the `id` cookie is
  92. not an integer number or if the `lang` cookie is empty. Additionally
  93. the `id` cookie value will be converted to an integer term:
  94. [source,erlang]
  95. CookiesMap = cowboy_req:match_cookies([{id, int}, {lang, nonempty}], Req).
  96. Note that if two cookies share the same name, then the map value
  97. will be a list of the two cookie values.
  98. A default value can be provided. The default will be used
  99. if the `lang` cookie is not found. It will not be used if
  100. the cookie is found but has an empty value:
  101. [source,erlang]
  102. #{lang := Lang} = cowboy_req:match_cookies([{lang, [], <<"en-US">>}], Req).
  103. If no default is provided and the value is missing, an
  104. exception is thrown.