Писательские навыки у автора пока неглубокие, если что не так, укажите великодушно, буду признателен
Cookie
1洛:大爷,楼上322住的是马冬梅家吧?
2
3大爷:马都什么?
4
5夏洛:马冬梅。
6
7大爷:什么都没啊?
8
9夏洛:马冬梅啊。
10
11大爷:马什么没?
12
13夏洛:行,大爷你先凉快着吧。
Прежде чем понять эти три концепции, мы должны сначала понять, что HTTPнет статусавеб-сервер, что такое без гражданства? Как и в классической сцене диалога в «Раздражении Шарлотты» выше, один диалог завершается, а следующий совершенно не знает, что случилось с последним. Если он используется только для управления статическими файлами на веб-сервере, не имеет значения, кто является другой стороной, просто прочитайте файл с диска и отправьте его. Но с непрерывным развитием сети, например, корзина в электронной коммерции может выполнять следующую серию действий только после запоминания личности пользователя. Итак, нам нужнонет статусаСервер помнит несколько вещей.
Так как же веб-сервер что-то запоминает? Поскольку веб-сервер ничего не запоминает, мы пытаемся запоминать что-то извне, что эквивалентно тому, что сервер прикрепляет небольшую заметку к каждому клиенту. Приведенное выше записывает некоторую информацию, возвращаемую нам сервером. Затем сервер видит эту маленькую заметку и знает, кто мы. ТакCookie
Кто его произвел? Файлы cookie генерируются сервером. Далее мы описываемCookie
Процесс производит
- Когда браузер обращается к серверу в первый раз, сервер не должен знать его личность в это время, поэтому создайте уникальные идентификационные данные в формате
key=value
, положить вSet-Cookie
поле вместе с ответным сообщением, отправленным в браузер. - Браузер видит
Set-Cookie
Поле позже узнает, что это идентификатор, предоставленный сервером, поэтому он сохраняется, и следующий запрос будет автоматическиkey=value
значение вCookie
поле на сервер. - После того, как сервер получает сообщение запроса, он обнаруживает, что
Cookie
Если в поле есть значение, пользователь может быть идентифицирован на основе этого значения, и может быть предоставлена персонализированная услуга.
Затем мы используем код, чтобы продемонстрировать, как генерируется сервер. Мы сами создаем фоновый сервер. Здесь я использую SpringBoot для сборки, и код, написанный в SpringMVC, выглядит следующим образом.
1@RequestMapping("/testCookies")
2public String cookies(HttpServletResponse response){
3 response.addCookie(new Cookie("testUser","xxxx"));
4 return "cookies";
5}
После старта проекта вводим путьhttp://localhost:8005/testCookies
, а затем просмотреть отправленный запрос. Вы можете увидеть запрос, отправленный при первом доступе к серверу на картинке ниже, и вы можете увидеть, что ответ, возвращенный сервером, содержитSet-Cookie
поле. И внутриkey=value
Значение именно то, что установлено на нашем сервере.
Затем мы снова обновляем страницу, чтобы увидеть, что она была установлена в теле запроса.Cookie
поле, и перенесите туда наше значение. Таким образом, сервер можетCookie
Значение в запоминает нашу информацию.
Далее, как насчет другого запроса? Да или нетCookie
Ты тоже возьмешь? Далее вводим путьhttp://localhost:8005
просить. Мы видим, чтоCookie
Поля по-прежнему переносятся.
затем браузерCookie
Где он хранится? Если вы используетеChrome
Если у вас есть браузер, выполните следующие действия.
- открыть на компьютере
Chrome
- В правом верхнем углу один клик
更多
значок ->设置
- Внизу щелкните
高级
- существует
隐私设置和安全性
Ниже нажмите Настройки сайта - нажмите
Cookie
-> Просмотреть всеCookie和网站数据
Затем вы можете искать управляемыйCookie
данные. Таким образом, браузер управляет этим за васCookie
данные, если в этот момент вы замените их наFirefox
другие браузеры, потому чтоCookie
просто хранился вChrome
внутри, так что сервер снова в кругу.Если вы не знаете, кто вы, вы дадитеFirefox
Вставьте маленькую заметку еще раз.
Настройки параметров в файлах cookie
Кстати говоря, вы должны знатьCookie
Это некоторые данные, которые сервер поручает браузеру хранить в клиенте, и эти данные обычно записывают ключевую идентификационную информацию пользователя. такCookie
Необходимо использовать другие средства для защиты, предотвращения утечки или кражи, эти средстваCookie
характеристики.
имя параметра | эффект | Метод настройки серверной части |
---|---|---|
Max-Age | Установите время истечения срока действия файла cookie в секундах. | cookie.setMaxAge(10) |
Domain | Указывает доменное имя, которому принадлежит файл cookie. | cookie.setDomain("") |
Path | Указывает путь, которому принадлежит файл cookie | cookie.setPath(""); |
HttpOnly | Сообщите браузеру, что этот файл cookie может передаваться только по Http-протоколу браузера, а другие способы доступа запрещены. | cookie.setHttpOnly(true) |
Secure | Сообщите браузеру, что этот файл cookie может быть передан только в протоколе безопасности Https, если это Http, передача запрещена. | cookie.setSecure(true) |
Ниже я кратко продемонстрирую использование и феномен этих параметров.
Path
Установить какcookie.setPath("/testCookies")
, то посещаемhttp://localhost:8005/testCookies
, мы видим, что путь слева совпадает с указанным нами путем, поэтомуCookie
Он отображается только в заголовке запроса, а затем мы посещаемhttp://localhost:8005
, мы не нашлиCookie
поле, этоPath
путь управления.
Domain
Установить какcookie.setDomain("localhost")
, то посещаемhttp://localhost:8005/testCookies
Мы обнаружили, что левая часть рисунка ниже имеетCookie
полей, но мы получаем доступhttp://172.16.42.81:8005/testCookies
, посмотрите на правую часть рисунка ниже, вы можете видеть, что нетCookie
поле. ЭтоDomain
Контролируемая доставка доменаCookie
.
Следующие несколько параметров не будут демонстрироваться один за другим, я считаю, что здесь все должны быть на своем месте.Cookie
Есть какое-то понимание.
Session
Cookie хранится на стороне клиента, сеанс хранится на стороне сервера, а клиент сохраняет только
SessionId
Выше мы знаем, чтоCookie
, так как браузер прошелCookie
Требование stateful реализовано, так зачем еще одно?Session
Шерстяная ткань? Здесь мы представляем, что если некоторая информация об учетной записи хранится вCookie
Если информация будет перехвачена, вся информация о нашей учетной записи будет потеряна. Так оно и появилосьSession
, сохранить важную информацию в сеансеSession
, браузер регистрирует толькоSessionId
ОдинSessionId
Соответствует запросу сеанса.
1@RequestMapping("/testSession")
2@ResponseBody
3public String testSession(HttpSession session){
4 session.setAttribute("testSession","this is my session");
5 return "testSession";
6}
7
8
9@RequestMapping("/testGetSession")
10@ResponseBody
11public String testGetSession(HttpSession session){
12 Object testSession = session.getAttribute("testSession");
13 return String.valueOf(testSession);
14}
Здесь мы пишем новый метод для тестированияSession
Как он генерируется, добавляем в параметры запросаHttpSession session
, а затем введите в браузереhttp://localhost:8005/testSession
Доступ можно увидеть в заголовке возврата сервера вCookie
сгенерировалSessionId
. тогда браузер запоминает этоSessionId
Вы можете взять этот идентификатор с собой при следующем посещении, и тогда вы сможете найти информацию, хранящуюся на сервере, на основе этого идентификатора.
В этот момент мы получаем доступ к путиhttp://localhost:8005/testGetSession
, открытие, которое мы выше сохранили вSession
информация в . ТакSession
Когда он истекает?
- клиент: и
Cookie
Срок действия тот же, если он не задан, то по умолчанию браузер закрывается и его уже нет, то есть при повторном открытии браузера в начальном заголовке запроса ничего нет.SessionId
. - Серверная сторона: срок действия серверной стороны действительно истек, то есть серверная сторона
Session
Как долго сохраненная структура данных была недоступна, по умолчанию 30 минут.
Теперь, когда мы знаемSession
Он управляется на стороне сервера, поэтому, возможно, у вас возникнет несколько вопросов, когда вы увидите это.Session
Где он был создан?Session
В какой структуре данных он хранится? Далее давайте посмотримSession
как это управляется.
Session
Управление осуществляется в контейнере, что такое контейнер?Tomcat
,Jetty
и т.д. все контейнеры. Далее возьмем наиболее часто используемыеTomcat
Возьмем примерTomcat
как это управляетсяSession
из. существуетManageBase
изcreateSession
используется для созданияSession
из.
1@Override
2public Session createSession(String sessionId) {
3 //首先判断Session数量是不是到了最大值,最大Session数可以通过参数设置
4 if ((maxActiveSessions >= 0) &&
5 (getActiveSessions() >= maxActiveSessions)) {
6 rejectedSessions++;
7 throw new TooManyActiveSessionsException(
8 sm.getString("managerBase.createSession.ise"),
9 maxActiveSessions);
10 }
11
12 // 重用或者创建一个新的Session对象,请注意在Tomcat中就是StandardSession
13 // 它是HttpSession的具体实现类,而HttpSession是Servlet规范中定义的接口
14 Session session = createEmptySession();
15
16
17 // 初始化新Session的值
18 session.setNew(true);
19 session.setValid(true);
20 session.setCreationTime(System.currentTimeMillis());
21 // 设置Session过期时间是30分钟
22 session.setMaxInactiveInterval(getContext().getSessionTimeout() * 60);
23 String id = sessionId;
24 if (id == null) {
25 id = generateSessionId();
26 }
27 session.setId(id);// 这里会将Session添加到ConcurrentHashMap中
28 sessionCounter++;
29
30 //将创建时间添加到LinkedList中,并且把最先添加的时间移除
31 //主要还是方便清理过期Session
32 SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
33 synchronized (sessionCreationTiming) {
34 sessionCreationTiming.add(timing);
35 sessionCreationTiming.poll();
36 }
37 return session
38}
В этот момент мы понимаемSession
Как он был создан, и после того, как он был созданSession
будет сохранен вConcurrentHashMap
середина. можно смотретьStandardSession
своего рода.
1protected Map<String, Session> sessions = new ConcurrentHashMap<>();
Все должны быть здесьSession
Есть простое понимание.
Сессия хранится в контейнере Tomcat, поэтому, если есть несколько серверных машин, сессия не может быть разделена между несколькими машинами.В настоящее время можно использовать распределенное решение для сессий, предоставляемое Spring, которое заключается в том, чтобы поместить сессию в Редис.
Token
Session
хранить проверяемую информацию на сервере и использоватьSessionId
соответствующие данные,SessionId
Хранится клиентом и будетSessionId
Оно также приносит прошлое, поэтому реализуется соответствие состояния. иToken
Сервер передает клиенту информацию о пользователе после кодировки Base64Url.Каждый раз, когда пользователь запрашивает, он будет приносить эту информацию, поэтому после того, как сервер получит эту информацию и расшифрует ее, он узнает, кто такой пользователь.Этот метод называется JWT (веб-токен Json).
Token
по сравнению сSession
Преимущество заключается в том, что при наличии нескольких серверных систем, поскольку клиент напрямую переносит данные при доступе, нет необходимости выполнять операцию совместного использования данных.
Преимущества токена
- Кратко: может пройти
URL
,POST
параметр или вHTTP
Отправляются параметры заголовка, потому что объем данных небольшой, а скорость передачи также высокая - Автономность: поскольку строка содержит информацию, необходимую пользователю, можно избежать множественных запросов к базе данных.
- Поскольку токен хранится на клиенте в виде Json, JWT является кросс-языковым.
- Нет необходимости сохранять информацию о сеансе на сервере, особенно подходит для распределенных микросервисов.
Структура JWT
Фактический JWT выглядит следующим образом: это очень длинная строка с.
разделен на три части
JWT состоит из трех частей
Header
это объект Json, который описывает метаданные JWT, обычно следующим образом
1{
2 "alg": "HS256",
3 "typ": "JWT"
4}
В приведенном выше коде атрибут alg представляет алгоритм подписи (алгоритм), по умолчанию используется HMAC SHA256 (записывается как HS256); атрибут typ представляет тип токена (type), а токен JWT единообразно записывается как JWT.
Наконец, преобразуйте приведенный выше объект JSON в строку, используя алгоритм Base64URL.
В качестве токена (токена) JWT в некоторых случаях может быть помещен в URL-адрес (например, api.example.com/?token=xxx). В Base64 есть три символа +, / и =, которые имеют особое значение в URL-адресах, поэтому их необходимо заменить: = опускается, + заменяется на -, а / заменяется на _. Это алгоритм Base64URL.
Payload
Часть Payload также является объектом Json, который используется для хранения данных, которые на самом деле необходимо передать.JWT официально указывает следующие официальные поля для выбора.
- iss (эмитент): Эмитент
- exp (время истечения): время истечения
- суб (тема): тема
- aud (аудитория): аудитория
- nbf (не раньше): время действия
- iat (выпущено в): выдано в
- jti (идентификатор JWT): число
Конечно, в дополнение к этим официально предоставленным полям мы также можем определить приватные поля самостоятельно.Ниже приведен пример
1{
2 "name": "xiaoMing",
3 "age": 14
4}
По умолчанию JWT не зашифрован, и любой может прочитать информацию, если она расшифрована Base64 в Интернете, поэтому обычно не помещайте секретную информацию в эту часть. Этот объект Json также используетсяBase64URL
Алгоритм для строки
Signature
Часть Signature предназначена для подписи данных двух предыдущих частей, чтобы предотвратить подделку данных.
Сначала необходимо определить секретный ключ.Этот секретный ключ известен только серверу и не может быть передан пользователю.Затем используйте алгоритм подписи, указанный в Заголовке (по умолчанию HMAC SHA256).После расчета подписи объедините три части заголовка, полезной нагрузки и подписи в одну строку, каждая часть с.
Разделите его и верните пользователю.
HS256 может создать подпись для данного образца данных с помощью одного ключа. Когда сообщение передается с подписью, получатель может использовать тот же ключ для проверки соответствия подписи сообщению.
Как использовать токен в Java
Выше мы представили некоторые понятия о JWT, как его использовать дальше? Сначала введите в проект пакет Jar.
1compile('io.jsonwebtoken:jjwt:0.9.0')
Затем кодируйте следующим образом
1// 签名算法 ,将对token进行签名
2SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
3// 通过秘钥签名JWT
4byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("SECRET");
5Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
6Map<String,Object> claimsMap = new HashMap<>();
7claimsMap.put("name","xiaoMing");
8claimsMap.put("age",14);
9JwtBuilder builderWithSercet = Jwts.builder()
10 .setSubject("subject")
11 .setIssuer("issuer")
12 .addClaims(claimsMap)
13 .signWith(signatureAlgorithm, signingKey);
14System.out.printf(builderWithSercet.compact());
Обнаружено, что выходной токен выглядит следующим образом
1eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0IiwiaXNzIjoiaXNzdWVyIiwibmFtZSI6InhpYW9NaW5nIiwiYWdlIjoxNH0.3KOWQ-oYvBSzslW5vgB1D-JpCwS-HkWGyWdXCP5l3Ko
На этом этапе вы можете расшифровать информацию, просто найдя в Интернете веб-сайт декодирования Base64.
Суммировать
Я считаю, что это должен увидеть каждыйCookie
,Session
,Token
Существует определенное понимание, а затем просмотрите важные моменты знаний
- Файлы cookie хранятся на стороне клиента
- Сессия хранится на сервере и может рассматриваться как список состояний. иметь уникальный идентификатор сеанса
SessionId
. может основываться наSessionId
Сохраненная информация запрашивается на стороне сервера. - Сеанс вызовет проблему, то есть проблему совместного использования сеанса, когда в бэкэнде несколько машин.Решение может использовать фреймворк, предоставляемый Spring.
- Токен похож на токен, без сохранения состояния, информация, необходимая серверу, закодирована в Base64 и помещена в токен, и сервер может напрямую декодировать содержащиеся в нем данные.
Кодовый адрес GitHub
Думаю, вы хотите прочитать
- Изучите эти вопросы по алгоритму связанных списков, и вы больше не будете бояться рукописных связанных списков для интервью.
- Трудно ли транзакциям Spring распространять свойства? Хватит это читать
- При разработке бэкэнд-фреймворка необходимо обратить внимание на
- Оптимизация процесса сжатия 20M файлов с 30 секунд до 1 секунды
- Почему переопределение equals() также переопределяет hashCode()
Справочная статья
- Cookies vs. Tokens: The Definitive Guide
- Тщательно понимать сеанс, cookie, токен
- Перспективный HTTP-протокол
- Компонент менеджера: анализ механизма управления сеансом Tomcat
- Начало работы с веб-токеном JSON
- SpringBoot интегрирует JWT для реализации проверки токенов
- JSON Web Token — безопасный обмен информацией между веб-приложениями