В Ruby on Rails для роботи з JWT (JSON Web Tokens) можна використовувати бібліотеку jwt
. Вона дозволяє створювати, підписувати та перевіряти токени. JWT використовується для аутентифікації користувачів шляхом передачі закодованої інформації, такої як ідентифікатор користувача, в безпечний спосіб.
Ось детальний гайд, як використовувати jwt в Rails:
1. Встановлення бібліотеки
Спочатку додайте gem jwt
в Gemfile
вашого проекту:
gem 'jwt'
Після цього виконайте команду:
bundle install
2. Налаштування секретного ключа
JWT токени підписуються секретним ключем. Ви можете зберігати його в змінних середовища або у файлі конфігурації Rails.
У файл config/secrets.yml
додайте:
development:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Встановіть змінну оточення SECRET_KEY_BASE
, або використайте іншу змінну, наприклад JWT_SECRET_KEY
.
3. Створення токена
Припустимо, ви хочете створювати токен після того, як користувач успішно пройшов аутентифікацію (наприклад, в SessionsController
).
require 'jwt'
class SessionsController < ApplicationController
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
token = encode_token({ user_id: user.id })
render json: { token: token }
else
render json: { error: 'Invalid email or password' }, status: :unauthorized
end
end
private
def encode_token(payload)
JWT.encode(payload, Rails.application.secrets.secret_key_base)
end
end
4. Декодування токена
Коли ви отримуєте запит із токеном (наприклад, у заголовку запиту), вам потрібно буде декодувати його, щоб отримати інформацію про користувача.
Ось приклад методу для декодування токена:
def decode_token(token)
begin
JWT.decode(token, Rails.application.secrets.secret_key_base, true, algorithm: 'HS256')[0]
rescue JWT::DecodeError
nil
end
end
Цей метод поверне інформацію з токена або nil
, якщо декодування не вдалося (наприклад, через неправильний або застарілий токен).
5. Додавання токена до заголовків
Зазвичай токен передається в заголовку запиту. Ви можете перевіряти токен у кожному запиті через before_action
в контролері.
class ApplicationController < ActionController::API
before_action :authorize_request
private
def authorize_request
token = request.headers['Authorization']
if token
decoded_token = decode_token(token.split(' ').last)
@current_user = User.find(decoded_token["user_id"]) if decoded_token
else
render json: { error: 'Unauthorized' }, status: :unauthorized
end
end
end
Тут використовується метод authorize_request
, який спочатку перевіряє наявність токена в заголовку, потім намагається його розбити (токен зазвичай передається у вигляді Bearer <токен>
), декодувати та знайти користувача за user_id
.
6. Робота з терміном дії токенів
JWT підтримує додавання терміну дії токена через exp
(expiration). Для цього можна додати поле в payload
.
def encode_token(payload)
exp = 24.hours.from_now.to_i
payload[:exp] = exp
JWT.encode(payload, Rails.application.secrets.secret_key_base)
end
Під час декодування можна додатково перевіряти термін дії:
def decode_token(token)
begin
decoded_token = JWT.decode(token, Rails.application.secrets.secret_key_base, true, algorithm: 'HS256')[0]
if decoded_token['exp'] && Time.at(decoded_token['exp']) > Time.now
decoded_token
else
nil
end
rescue JWT::ExpiredSignature
nil
rescue JWT::DecodeError
nil
end
end
7. Безпека
- Використовуйте довгий і випадковий секретний ключ для підпису токенів.
- Зашифровані токени повинні мати короткий термін дії (наприклад, кілька годин).
- Використовуйте HTTPS для передачі токенів, щоб уникнути атаки типу «людина посередині» (MITM).
Висновок
Цей приклад показує основні кроки для інтеграції JWT з Ruby on Rails, включаючи створення, декодування та перевірку токенів. Ви можете розширити цей підхід, додаючи ролі користувачів, оновлення токенів (refresh tokens) і додаткові механізми безпеки, такі як обмеження терміну дії сесій.