RailsでのSession, Cookie利用について

# 概要
Rails環境での`Cookie`, `Session`利用についてまとめました。

`Cookie`, `Session`そのものは知っているけど、
`Rails`での利用方法がわからない方向けに執筆しています。

# Session, Cookie について
セッション...？ クッキー...？ という方は以下の記事をご一読ください。

https://www.ntt.com/bizon/glossary/j-s/session.html

https://www.ntt.com/about-us/hp/webbeacon.html

# Session

### Sessionデータの保存先について
Railsでは、`Session`データの保存場所として、以下を指定することができます。
データの保存先として、`Cookie`や`DB`を利用できることを認識しておきましょう！

| **ストアタイプ**          | **説明**                                                                                                             | 
| ------------------------- | -------------------------------------------------------------------------------------------------------------------- | 
| `cookie_store`       | クッキーにセッションデータを保存。<br>デフォルトではセッションクッキー（ブラウザ終了時に削除）として設定。<br> `key`を省略した場合、`cookie`名は`_session_id`となる | 
| `cache_store`         | Rails のキャッシュストア（例: `Memcached`、`Redis`）を利用してセッションデータを保存。                             | 
| `active_record_store`    | データベースのテーブル（デフォルトは `sessions` テーブル）にセッションデータを保存。                           | 
| `mem_cache_store`     | Memcached を使用してセッションデータを保存。                                                                   | 

 保存先の設定は`config/application.rb`で行います。
- `config.session_store`で保存先を指定
- `Session`を利用するためのミドルウェアを有効化

```ruby
# config/application.rb
module SampleApp
  class Application < Rails::Application
    # ...
    
    # ここから
    config.session_store :cookie_store
    config.middleware.use ActionDispatch::Cookies
    config.middleware.use config.session_store, config.session_options
    # ここまで
  end
end
```

`Session`データを取り扱う前に上記設定が必要になるため、忘れずに対応しましょう！

### Sessionのアクセス
```ruby
# Write
session[:test_session] = "test_session"

# Read
session[:test_session]
```

これだけです。
簡単ですね...！

# Cookie
続いては`Cookie`を見ていきましょう。

### Cookieのアクセス
```ruby
# Write
cookies[:test_cookie] = "test_cookie"

# Read
cookies[:test_cookie]
```

こちらも簡単ですね。
`cookie`にはよく利用するオプションがいくつかありますので、以下で詳しく解説します。


### `Cookie` のオプション
Cookieにはさまざまなオプションを指定できます。
以下オプションは、中でも利用機会が多いので、必ず覚えておきましょう。
- `http_only`
- `secure`
- `expires`

#### 設定例
```ruby
cookies[:test_cookie] = { value: "test_cookie", httponly: true, secure: true }
```

| **オプション名** | **概要**                                                                                                                                                   |
|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `http_only`       | CookieをHTTPプロトコル経由でのみアクセス可能にする。<br>JavaScriptからのアクセスを防ぎ、XSS攻撃から保護。                |
| `secure`          | HTTPS接続時のみCookieを送信する。<br>Cookieが暗号化されていない接続で送信されるのを防ぐ。                                                 |
| `permanent`       | Cookieの有効期限を永久（約20年後）に設定する。<br>Cookieを長期間保持させたい場合に使用します。                |
| `signed`          | Cookieの値を署名付きで保存。<br>Cookieがクライアント側で改ざんされていないことを検証できる。<br>署名/検証に利用するキーは`credentials`で管理される。                                         |
| `expires`         | Cookieの有効期限を具体的な日時で設定する<br>                                                      |
| `max_age`         | Cookieの有効期間を秒数で設定する<br>                           |
| `domain`          | Cookieが有効となるドメインを指定する。<br>サブドメインとCookieを共有したい場合に使用する。                                                             |
| `path`            | Cookieが有効となるパスを指定する。<br>特定のパスでのみCookieを送信したい場合に設定します。                                                                 |
| `samesite`        | CookieのSameSite属性を設定する<br>`:lax`、`:strict`、`:none`のいずれかを指定し、クロスサイトリクエストに対するCookieの送信ポリシーを制御する。                  |
| `encrypted`       | Cookieの値を暗号化して保存する。<br>Cookieの内容が第三者に読み取られることを防ぐ。                                                           |
| `serializer`      | Cookieのデータシリアライザを指定する。<br>`:json`や`:marshal`を指定して、Cookieのデータ形式を制御する。                                           |


# ハンズオン
それでは実際に`Session`（`cookie_store`）を利用してみましょう。

## 準備

まずは、`config/application.rb`でセッションストアの設定を行います。

```ruby
# config/application.rb
module SampleApp
  class Application < Rails::Application
    # ...
    # 追加
    config.session_store :cookie_store, key: "test_app"
    config.middleware.use ActionDispatch::Cookies
    config.middleware.use config.session_store, config.session_options
  end
end
```

次に、対応するコントローラーとルーティングを定義します。
`Rake`コマンドを使用しましょう。

```bash
rails g controller custom/cookies_controller index
```

```ruby
# app/controllers/custom/cookies_controller.rb
class Custom::CookiesController < ApplicationController
  def index
    session[:test_session] = { value: "test_session" }
    cookies[:test_cookie] = { value: "test_cookie" }

    render json: {
      message: "Session and Cookie have been set.",
      session: session[:test_session],
      cookies: cookies[:test_cookie]
    }
  end
end

```

```ruby
# config/routes.rb
namespace :custom do
  get "cookies/index"
end
```

以上で設定は完了です。

## アクセス
ブラウザで `http://localhost:3000/custom/cookies/index` にアクセスしましょう。
開発者ツールの `Application` タブから `Cookie` 情報を確認します。


`session`に格納したデータ（`_session_id`）と
`cookie`に格納したデータ（`test_cookie`）それぞれ確認できれば正常動作になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842674/ca5752b4-b4b8-c4d8-3b6c-b7671758872f.png)


# まとめ
お疲れ様でした！
これで基本的な取り扱いについてはマスターできたと思います！