Поймите Cookie, Session, Token, Jwt и реальный бой в одной статье.
Поймите Cookie, Session, Token, Jwt и реальный бой в одной статье.

Понимание файлов cookie, сеанса, токена и Jwt в одной статье

Cookie

Cookieдахранится вклиент(браузер пользователя)изнебольшие фрагменты данных,Может использоваться для запоминания информации, связанной с пользователем.,Например, учетные данные для входа или настройки. Они отправляются на сервер с каждым HTTP-запросом.,и может быть прочитан сервером для поддержания сеанса или персонализации взаимодействия с пользователем.

Например: Представьте, что пользователь заходит на сайт банка. Сервер создает файл cookie, содержащий идентификатор сеанса, и отправляет его обратно в браузер пользователя через заголовок Set-Cookie. Браузер сохраняет этот файл cookie и отправляет его обратно на сервер при последующих запросах, позволяя серверу распознавать пользователя и поддерживать его вход в систему при нескольких загрузках страниц.

Session

会话用于跟踪用户существовать多个页面请求期间из状态。它们通常хранится всерверная часть,и связан с уникальным идентификатором сеанса (обычно идентификатор сеанса),Идентификатор сеанса отправляется клиенту в виде файла cookie. Сессии позволяют серверу запоминать информацию о пользователе во время его посещения.

Например: Пользователи совершают покупки на сайтах электронной коммерции. Сервер создает сеанс для пользователя, сохраняя его товары в корзине покупок и другую соответствующую информацию. Идентификатор сеанса отправляется в браузер пользователя в виде файла cookie. Когда пользователь перемещается по сайту, идентификатор сеанса в файле cookie позволяет серверу получать доступ к данным сеанса пользователя, обеспечивая пользователю беспрепятственный процесс совершения покупок.

Token

Tokendaa форма аутентификации статуса никто,клиентиметьжетон,Обычно даа строка,Используется для аутентификации запросов к серверу. Токен не требует, чтобы сервер отслеживал статус пользователя.,Потому что вся необходимая информация закодирована в самом жетоне.

Например: Пользователи хотят получить доступ к своей электронной почте через мобильные приложения. Приложение отправляет запрос с учетными данными пользователя на сервер провайдера электронной почты. После успешной аутентификации сервер выдает токен доступа. Приложение сохраняет этот токен и использует его в последующих запросах API для доступа к электронной почте пользователя.

JWT (JSON Web Tokens)

JWTдаa компактный、Безопасный метод представления претензий между двумя сторонами. JWTда содержит заголовок、нагрузкаи签名изJSON-объект。JWTМожет использоваться для аутентификациииавторизованный пользователь,Они самостоятельны,Это означает, что вся информация, необходимая для их проверки, содержится в самом жетоне.

Например: Разработчик создает веб-приложение с функцией единого входа. После входа пользователя в систему сервер генерирует JWT, содержащий идентификатор и разрешения пользователя. Этот JWT отправляется клиенту и сохраняется локально. Когда пользователь хочет получить доступ к защищенному ресурсу, клиент включает JWT в заголовок авторизации HTTP-запроса. Сервер проверяет JWT и, если он действителен, предоставляет доступ к ресурсу.

Разница между четырьмя

Ниже приведена таблица, иллюстрирующая их различия в различных аспектах.

характеристика

Cookie

Session

Token

JWT

определение

Данные отправляются с сервера в браузер для отслеживания статуса.

Ведение журнала состояния сеанса на стороне сервера

Токен безопасности для аутентификации и обмена информацией

Облегченный механизм аутентификации на основе JSON

место хранения

клиент

серверная часть

клиент(LocalStorageилиCookie)

клиент(LocalStorageилиCookie)

безопасность

Низкий, легко быть украденным или подделанным

Выше данные не раскрываются в клиенте

Выше, особенно для криптотокенов

Высший, содержит подпись, проверяет целостность данных

Междоменная поддержка

Не поддерживается по умолчанию, может быть достигнуто через настройки

Не поддерживается, зависит от файлов cookie

Поддержка, не полагается на файлы cookie

Поддержка, не полагается на файлы cookie

ограничение размера

Около 4 КБ

никтоограничение размера

никтоограничение размера

Обычно меньше, но под влиянием ограничения размера JSON.

жизненный цикл

Срок годности можно установить

Обычно срок действия истекает после закрытия пользователем браузера или истечения времени ожидания.

Срок годности можно установить

Срок годности можно установить

Поддержка без гражданства

Не поддерживается, зависит от файлов cookie

Поддерживается, но сеанс должен основываться на файлах cookie.

Поддерживается, сервер без сохранения состояния

Поддерживается, сервер без сохранения состояния

Применимые сценарии

Простое отслеживание сеансов, пользовательские настройки

Сценарии, требующие от сервера запоминания статуса пользователя

Мобильные приложения, аутентификация API, междоменные запросы

Веб-приложения, мобильные приложения, единый вход

Междоменные проблемы

Есть междоменные ограничения

никто Междоменные проблемы, но необходимо обрабатывать совместное использование сеансов при развертывании кластера.

никто Междоменные проблемы, подходят для междоменной аутентификации

никто Междоменные проблемы, подходят для междоменной аутентификации

Давление сервера

никто

Давление сервера будет увеличиваться при высоком уровне параллелизма

Низкий, подходит для крупномасштабного развертывания

Низкий, подходит для крупномасштабного развертывания

тип данных

Поддерживает только строки

Может хранить данные любого типа

Может хранить данные любого типа

Может хранить неконфиденциальную информацию

Ниже мы представляем различия между четырьмя из них, исходя из их преимуществ и недостатков.

механизм

Введение

преимущество

недостаток

Применимые сценарии

Cookie

Храните небольшие текстовые файлы в клиенте

Простой в использовании, поддерживает междоменный доступ.

Ограниченная емкость хранилища, уязвимая для атак CSRF.

Храните небольшие объемы неконфиденциальной информации, такой как пользовательские настройки и т. д.

Session

Хранить данные, связанные с конкретным сеансом пользователя, на сервере.

безопасность выше и может хранить конфиденциальную информацию

Повышенная нагрузка на сервер и необходимость поддерживать состояние сеанса.

Хранит более конфиденциальную информацию, такую ​​как статус входа пользователя, содержимое корзины покупок и т. д.

Token

Токены, используемые для аутентификации и авторизации

никтостатус、Расширяемый、Междоменный домен

Необходимы дополнительные меры безопасности для защиты жетона и увеличения нагрузки на сеть передачи.

Аутентификация API, особенно в распределенных системах

JWT

Открытый стандарт на основе JSON для безопасной передачи информации.

Расширяемый、автономный、никому требуется статус сервера

После издания никто закон не отменяется、Увеличение нагрузки на сеть передачи данных

Междоменная аутентификация, особенно в распределенных системах и сценариях единого входа (SSO).

Резюме: файлы cookie и Session да Традиционный серверный механизм управления сессиями, при этом Token и JWT Тогда да — это более гибкий и безопасный механизм аутентификации и авторизации, подходящий для распределенных систем и сценариев приложений, в которых внешний и внутренний серверы разделены. JWT да Token из一种实现方式,具有更高из可移植секси Расширяемыйсекс。

Проект реального боя

Вот некоторые практические различия между да в Springboot

Язык кода:javascript
копировать
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
​
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
​
@SpringBootApplication
@RestController
public class AuthApplication {
​
    private final String SECRET_KEY = "secretkey123"; // Ключ шифрования JWT
​
    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class, args);
    }
​
    @GetMapping("/setCookie")
    public String setCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie("user", "john_doe");
        cookie.setMaxAge(3600); // 设置Cookieизжизненный цикл 1 час
        response.addCookie(cookie);
        return «Настройка файлов cookie прошла успешно!»;
    }
​
    @GetMapping("/setSession")
    public String setSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute("user", "john_doe");
        return "Сессия успешно установлена!";
    }
​
    @GetMapping("/getCookie")
    public String getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("user")) {
                    return «Получить информацию о пользователе из файлов cookie:» + cookie.getValue();
                }
            }
        }
        return «Куки не найден!»;
    }
​
    @GetMapping("/getSession")
    public String getSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String user = (String) session.getAttribute("user");
        if (user != null) {
            return «Получить информацию о пользователе из сеанса:» + user;
        }
        return «Сессия не найдена!»;
    }
​
    @PostMapping("/login")
    public String login(@RequestBody UserCredentials credentials) {
        // В практических приложениях пользователи должны проходить аутентификацию здесь, например, проверять совпадение имени пользователя и пароля в базе данных.
        if (credentials.getUsername().equals("john_doe") && credentials.getPassword().equals("password123")) {
            // Создать токен
            String token = Jwts.builder()
                    .setSubject(credentials.getUsername())
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // Установите срок действия токена на 1 час.
                    .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                    .compact();
            return «Вход успешен! Сгенерирован токен:» + token;
        } else {
            return «Неверное имя пользователя или пароль!»;
        }
    }
​
    @GetMapping("/secure")
    public String secure(HttpServletRequest request) {
        // В практических приложениях валидность токена должна быть проверена здесь.
        String token = request.getHeader("Authorization").replace("Bearer ", "");
        String user = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
        return «Доступ к защищенной конечной точке успешен, пользователь:» + user;
    }
​
    static class UserCredentials {
        private String username;
        private String password;
​
        // Getters and setters
        public String getUsername() {
            return username;
        }
​
        public void setUsername(String username) {
            this.username = username;
        }
​
        public String getPassword() {
            return password;
        }
​
        public void setPassword(String password) {
            this.password = password;
        }
    }
}
​

Я считаю, что прочитав этот код, вы уже должны понять самую основную разницу.

После этого я порекомендую некоторые из лучших практик реального боя (это не значит, что они лучшие, это лучшие в моем случае. Если есть какие-либо ошибки, вы можете обсудить их в области комментариев).

Сначала вам нужно добавить Spring SecurityиJWTиз依赖项到你изpom.xmlв файле:

Язык кода:javascript
копировать
<dependencies>
    <!-- Spring Security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!-- JSON Web Token Support -->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

Затем вы можете создать служебный класс JWT для создания и проверки JWT:

Язык кода:javascript
копировать
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
​
import java.util.Date;
import java.util.function.Function;
​
@Component
public class JwtUtils {
    private String secret = "yourSecretKey"; // твой ключ
​
    public String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + 3600000)) // Срок действия истекает через 1 час
                .signWith(SignatureAlgorithm.HS256, secret)
                .compact();
    }
​
    public Boolean validateToken(String token, String username) {
        final String usernameFromToken = getUsernameFromToken(token);
        return (usernameFromToken.equals(username) && !isTokenExpired(token));
    }
​
    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }
​
    public Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token, Claims::getExpiration);
    }
​
    public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }
​
    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }
​
    private Boolean isTokenExpired(String token) {
        final Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }
}

Затем создайте контроллер для обработки запроса на вход и сгенерируйте JWT:

Язык кода:javascript
копировать
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.web.bind.annotation.*;
​
@RestController
@RequestMapping("/auth")
public class AuthController {
​
    @Autowired
    private AuthenticationManager authenticationManager;
​
    @Autowired
    private JwtUtils jwtUtils;
​
    @PostMapping("/signin")
    public String signin(@RequestBody User user) throws AuthenticationException {
        authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword())
        );
        return jwtUtils.generateToken(user.getUsername());
    }
​
    @GetMapping("/info")
    public String info(@RequestParam String token) {
        if (jwtUtils.validateToken(token, "user")) {
            return "Token is valid!";
        } else {
            return "Token is not valid!";
        }
    }
}

Наконец, вам необходимо настроить Spring Security для использования JWT для аутентификации:

Язык кода:javascript
копировать
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
​
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
​
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .httpBasic(); // Используйте базовую аутентификацию
    }
​
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
            .password("password")
            .roles("USER");
    }
}

Это можно использовать только как план для собственного обучения.,Если проект да выйдет в интернет,Также необходимо учитывать множество вопросов безопасности.

Вот некоторые меры:

меры безопасности

Используйте HTTPS

Для защиты данных, передаваемых между клиентскими серверами, безопасность,Вам следует использовать HTTPS. HTTPS шифрует данные через SSL/TLS,Предотвратите атаки типа «человек посередине» и утечку данных.

Весной Включить HTTPS при загрузке:

1.существоватьapplication.propertiesилиapplication.yml中配置服务器изSSL属секс

Язык кода:javascript
копировать
server.port=8443
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=yourpassword
server.ssl.key-password=yourkeypassword

2.Создать файл хранилища ключей(keystore.jks)并配置适当из密码。

3. Убедитесь, что ваше приложение доступно через порт 8443, который является портом по умолчанию для HTTPS.

Управление ключами

Для JWT, Управление ключамидом жизненно важно. Вам следует использовать безопасный способ хранения и доступа к ключу подписи.,И ключи меняйте регулярно.

Управление ключамилучшие практики:

  1. Не прописывайте ключи в своем коде.
  2. Используйте специализированное Управление ключами систем, таких как AWS KMS、HashiCorp Хранилище или другое.
  3. Регулярно заменяйте ключи и следите за тем, чтобы старые ключи больше не использовались для подписи новых JWT.

Предотвращение CSRF-атак

Подделка межсайтовых запросов (CSRF) — это атака, при которой злоумышленник может использовать удостоверение пользователя, прошедшее проверку подлинности, для выполнения неожиданных операций без ведома пользователя.

Весной Предотвратить CSRF в безопасности:

  1. Убедитесь, что все конфиденциальные операции выполняются через запросы POST.,И не даGET.
  2. Использование Spring Securityиз@csrfProtectionаннотация для включенияCSRFЗащищать。
  3. существовать表单提交时使用_csrfжетон。
Язык кода:javascript
копировать
@PostMapping("/some-protected-action")
@csrfProtection
public String someProtectedAction(@ModelAttribute SomeData data, @RequestParam("csrfToken") String csrfToken) {
    // твоя бизнес-логика
}

другоймеры безопасности

  • Используйте новейшие платформы безопасности и библиотеки.
  • Зависимости регулярно обновляются для устранения известных уязвимостей безопасности.
  • Внедрите проверку ввода для предотвращения атак путем внедрения.
  • Внедрите кодирование вывода для предотвращения атак с использованием межсайтовых сценариев (XSS).
  • Ограничьте количество попыток ввода пароля, чтобы предотвратить атаки методом перебора.
  • Внедрите списки управления доступом (ACL), чтобы ограничить доступ к конфиденциальным ресурсам.
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose