Чи коли-небудь ви замислювались, як ваш додаток пам'ятає, що ви увійшли в систему? Що відбувається за лаштунками, щоб підтримувати вашу сесію під час переходів між сторінками або відправки запитів до API? І якщо ви розробник на Rails, чи задумувались ви, як Rails все це обробляє за вас?
Я цього не робив — до того моменту, коли мені задали, здавалося б, просте питання:
“Як працює аутентифікація на основі сесії в Rails?”
Я почав впевнено пояснювати, як ідентифікатор сесії зберігається в cookies і як дані сесії обробляються на сервері. Однак, коли дискусія поглибилась, я зрозумів, що лише почав розбиратись у цьому. На відміну від багатьох розробників на Rails, я використовував абстракції Rails, не зовсім розуміючи, що відбувається під капотом.
Цей момент став для мене поштовхом до вивчення того, як Rails обробляє аутентифікацію на основі сесії, які є варіанти зберігання сесій та яку роль в цьому процесі відіграють cookies. Дозвольте розповісти вам про все, що я дізнався, крок за кроком.
Що таке аутентифікація на основі сесії?
Аутентифікація на основі сесії — це механізм, який дозволяє серверу зберігати стан користувача між окремими запитами. Ось як це зазвичай працює:
- Користувач входить в систему з дійсними даними для авторизації.
- Сервер генерує сесію і асоціює її з ідентифікатором сесії.
- Цей ідентифікатор сесії відправляється клієнту і зберігається в cookies браузера.
- Кожен наступний запит від клієнта включає цей ідентифікатор сесії у своїй cookies.
- Сервер отримує дані сесії та здійснює аутентифікацію користувача, використовуючи ідентифікатор сесії.
Rails і CookieStore
За замовчуванням, Rails використовує CookieStore для зберігання даних сесії безпосередньо в браузері клієнта у вигляді cookie. Ось як це відбувається.
- Створення сесії
- Під час входу користувача генерується сесія, і дані сесії серіалізуються. Наприклад,
{“user_id”: 1 }
- Підпис та шифрування
- Підписання — серіалізовані дані сесії хешуються, використовуючи secretkeybase, щоб забезпечити, що дані не були змінені.
- Починаючи з Rails 5, дані сесії шифруються для конфіденційності.
- Зберігання cookies:
- Підписані, зашифровані дані сесії зберігаються в браузері клієнта у вигляді cookie.
Приклад cookie (дефігурується)
_my_app_session=eyJ1c2VyX2lkIjoxfQ== – 1ab2c3d4e5f6
- _myappsession: Назва cookie; налаштовується в Rails.
- eyJ1c2VyX2lkIjoxfQ=: Base64-encode даних сесії: {“user_id”: 1}
- – 1ab2c3d4e5f6: Підписаний хеш, щоб забезпечити цілісність даних.
- Перевірка сесії
- Коли браузер повертає cookie, Rails перевіряє підпис за допомогою secretkeybase.
- Якщо перевірка успішна, дані сесії дешифруються та десеріалізуються.
- Сесія тепер доступна як session[:user_id].
Що відбувається при використанні серверного зберігання сесій?
Коли ви використовуєте серверне зберігання сесій (наприклад, Redis, база даних), поведінка трохи змінюється:
- Ідентифікатор сесії в cookie:
- Тепер cookie містить лише ідентифікатор сесії, а не дані сесії.
- Приклад cookie:
_my_app_session=1a2b3c4d5e6f7g8h
- Дані сесії на сервері:
- Дані сесії зберігаються в налаштованому серверному сховищі (наприклад, Redis, база даних).
- Rails отримує дані сесії для кожного запиту, використовуючи ідентифікатор сесії з cookie.
- Запити API:
- Ідентифікатор сесії в cookie повинен бути включений в кожен запит (наприклад, через заголовок Cookie). Наприклад (запит — GET /profile),
Cookie: _my_app_session=1a2b3c4d5e6f7g8h.
Cookies в Rails з безпекою
Для забезпечення безпеки сесія в Rails налаштовує такі параметри для cookies:
- domain: Визначає домен, під яким cookie є дійсним.
Використовуйте example.com для налаштування cookie для всіх піддоменів. - path: Обмежує cookie певним шляхом, таким як /api.
- secure: Забезпечує передачу cookie лише через HTTPS.
- httponly: Блокує доступ до cookie з JavaScript.
- samesite: Обмежує надсилання cookie разом з міжсайтовими запитами (:lax або :strict).
Конфігурація Rails прикладу
Rails.application.config.session_store :cookie_store,
key: '_my_app_session',
domain: '.example.com', # Підтримка піддоменів
path: '/', # Дійсно для всіх шляхів
secure: Rails.env.production?, # HTTPS тільки в продукційному середовищі
httponly: true, # Запобігання доступу з JavaScript
same_site: :lax # Зменшення ризиків CSRF
Типи сховищ сесій в Rails
Rails підтримує кілька варіантів зберігання сесій, кожен з яких має свої переваги та недоліки:
- CookieStore (за замовчуванням)
Зберігає дані сесії в cookie браузера.
- Переваги: Безстатеве, просте, не потребує зберігання на сервері.
- Недоліки: Обмежене до 4 КБ даних, потенційні ризики безпеки при неправильному налаштуванні.
- CacheStore
Зберігає дані сесії в кеші Rails (наприклад, Redis, Memcached).
- Використання: Для швидшого доступу до більших даних сесії.
- Конфігурація:
Rails.application.config.session_store :cache_store
- ActiveRecordStore
Зберігає дані сесії в базі даних.
- Використання: Персистентні сесії, які зберігаються після перезапуску сервера.
- Конфігурація:
Rails.application.config.session_store :active_record_store
- RedisStore
Зберігає дані сесії в Redis.
- Використання: Розподілені системи або додатки, що вимагають високої масштабованості.
- Конфігурація:
Rails.application.config.session_store :redis_store, servers: 'redis://localhost:6379/0/session'
- NullStore
Повністю вимикає сесії.
- Використання: Безстатеві API, де сесії не потрібні.
- Конфігурація:
Rails.application.config.session_store :null_store
Уроки, які я засвоїв
- Підпис та шифрування сесій:
- Rails підписує та шифрує дані сесії за замовчуванням, гарантуючи як цілісність, так і конфіденційність.
- Типи сховищ сесій:
- Використовуйте CookieStore для простих додатків з маленькими даними сесії.
- Використовуйте RedisStore або CacheStore для масштабованості.
- Використовуйте ActiveRecordStore для збереження сесій після перезапуску сервера.
- Безпека cookie:
- Завжди налаштовуйте secure, httponly та same_site для безпечного оброблення сесій.
- Торгові компроміси:
- Те, чи зберігати дані сесії на стороні клієнта чи сервера, визначає різницю між продуктивністю, масштабованістю та безпекою.
Висновок
Rails значно спростив управління сесіями. Однак розуміння того, як це працює, дозволяє писати кращий та безпечніший код. Не має значення, чи використовуєте ви CookieStore, Redis чи навіть базу даних, завжди налаштовуйте управління сесіями відповідно до конкретних потреб вашого додатку.
Наступного разу, коли хтось запитає: “Як Rails обробляє сесії?” – ви будете готові дати відповідь.
Який тип сховища сесій ви використовуєте в Rails? Поділіться в коментарях!
Перекладено з: Demystifying Session-Based Authentication in Rails