前回、RailsでセッションとCookieを操作する方法でRailsにおけるセッションとCookieの操作方法について紹介しました。
前回の記事のRailsアプリケーションはモノリス前提でしたが、今回はAPIモードでCookieを作成する方法について紹介します。railsのバージョンは6.0.4
を利用しています。
目次
基礎知識について
フロントエンドとバックエンドが分かれた構成のアプリケーションでCookieを作成する方法
「APIのレスポンスでCookieにセットする値を返し、APIから取得した値をフロントでCookieにセットする」という方法と、「Set-Cookiesがヘッダに含まれたレスポンスをAPIで返す(フロントはレスポンスを受け取るだけ)」という方法の2種類があります。
今回は後者の方法についての紹介になります。
Rails API(サーバサイド)でCookieを作成するメリットについて
ITPの影響を受けない
ITP (Intelligent Tracking Prevention)とはプライバシー保護の目的でSafariブラウザに実装されたサイトトラッキングの抑制機能です。
Cookieには自社サーバから発行されるファーストパーティCookie(1st party cookies)と、他社サーバから発行されるサードパーティCookie(3rd party cookies)の2種類があります。
JavaScriptを利用して作成されたファーストパーティCookieの有効期限はITP 2.1では7日間、ITP 2.2では24時間です。1 2
フロントエンド、つまりJavaScriptでCookieを作成する際はITPの影響を受けますが、サーバサイドでCookieを作成する場合は影響を受けません。
フロントエンド(JavaScript)でCookieを操作する必要がなくなるためセキュア
フロントエンドでCookieを作成する場合、JavaScriptでCookieを操作することになります。
JavaScirptによる操作が許可されたCookieの場合、XSS(クロスサイトスクリプティング)の考慮が必要になります。
サーバサイドでCookieを作成することでJavaScriptによる操作を許可しないHttpOnly属性を付与できるためセキュアにCookieのやりとりができます。
RailsアプリケーションでCookieを操作する場合はAction Controller
のcookies
メソッドを利用します。3
デフォルトのRails APIモードの場合、例えば以下のようなControllerにアクセスするとundefined local variable or method cookies for xxxx
というNameError
が返ってきます。
def index
cookies[:user_id] = 1
end
Rails APIモードでCookieを作成するためにやること
Rails APIモードでCookieを作成するには以下の2つの設定が必要です。
- ActionController::Cookiesをinclude
- ActionDispatch::Cookiesを読み込む
ActionController::Cookiesをinclude
cookies
メソッドが定義されているActionController::Cookies
をincludeします。
app/controllers/application_controller.rb
class ApplicationController < ActionController::API
include ActionController::Cookies
end
ActionDispatch::Cookiesを読み込む
Rack middlewareのActionDispatch::Cookies
を読み込みます。
config/application.rb
module ExampleApp
class Application < Rails::Application
...
...
config.middleware.use ActionDispatch::Cookies
end
end
動作確認
Cookieの作成方法
例えば以下のようなControllerにアクセスするとSet-Cookie: user_id=1; path=/
がヘッダにセットされたレスポンスが返ってきます。
def index
cookies[:user_id] = 1
end
$ curl -i http://localhost:3001/
HTTP/1.1 200 OK
(略)
Set-Cookie: user_id=1; path=/
(略)
ブラウザのCookieを確認すると先ほど定義したキーと値がセットされていることがわかります。
Cookieの取得方法
coookie[キー名]
あるいはrequest.cookies
でフロントエンドからのリクエストと一緒に送られたCookieを確認できます。
例えば、user_id
という値が1
のCookieを取得する方法は以下の通りです。
2: def index
=> 3: binding.pry
> cookies[:user_id]
=> "1"
> request.cookies
=> {"user_id"=>"1"}
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!
Rails APIモードでCookieを作成する方法について書きました。
フロントとバックエンドが分かれた構成のWebアプリの場合、サーバサイドでCookieを作成することで『ITPの影響を受けない』『httpOnly属性を付与したセキュアなやり取りが可能』といったメリットがあります。https://t.co/h0QdPKRpNf— 仁科俊晴@エンジニア (@nishina555) February 5, 2022