はじめに

簡易的に「あなたはxx歳以上ですか?」の年齢認証ページを挟む方法について整理した。

前提や要件は以下。

  • ユーザー登録なし
  • ページ表示前に単純な年齢認証を挟む
  • Yes を選択したら、表示しようとしていたページに移動
  • No を選択したら、トップページにリダイレクト
  • 一度 Yes を選択したら、(指定期間内は)その後の年齢認証は行わない

TL;DR

ちょっと分かりづらいけど。

  • cookie に「年齢認証結果」と「本来表示しようとしていたページ(URL)」を保持すると OK
  • 「年齢認証結果」がなければ、「本来表示しようとしていたページ(URL)」を保持しつつ、年齢認証ページにリダイレクト
  • 年齢認証で Yes が選ばれたら、「年齢認証結果」を保持して、「本来表示しようとしていたページ(URL)」にリダイレクト

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. ルーティング
    2. コントローラ
    3. ビュー
    4. 処理の流れ
  5. まとめ
  6. その他・メモ
  7. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88

$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

$ rails -v
Rails 5.2.3

詳細

何らかの商品ページにアクセスしようとした時に、年齢認証を挟むイメージ。

ルーティング

config/routes.rb

1
2
3
4
5
6
7
8
Rails.application.routes.draw do
# 商品ページ
get 'items/:id', to: "item#show"
# 年齢認証ページ
get 'verify_age', to: "item#verify_age"
# 年齢認証 Yes のルート(すぐにリダイレクトするので View 無し)
get 'verified', to: "item#verified"
end

コントローラ

以下の 2つの cookie を利用する

  • over18: 18歳以上なら yes で保持
  • original_url: ユーザーが表示しようとしているページ、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class ItemController < ApplicationController
before_action :verify_age_cookie, only: [:show]

def show
@item = Item.find(params[:id])
end

def verify_age
end

def verified
write_age_cookie
return redirect_to cookies[:original_path]
end

private
def verify_age_cookie
# over18 が存在しない、yes ではない場合は、年齢認証ページ(verify_age)にリダイレクト
if cookies[:over18].blank? || cookies[:over18] != 'yes'
# 年齢認証 Yes で表示するページ(もともと表示しようとしていたページ)
cookies[:original_path] = request.fullpath
return redirect_to verify_age_path
end
end

def write_age_cookie
# cookie をどの程度保持するかは要件次第
cookies[:over18] = { value: "yes", expires: 1.years.since }
end
end

ビュー

app/views/item/verify_age.htlm.slim

1
2
3
4
5
6
p
| あなたは18才以上ですか?
div
= link_to "はい", verified_path
div
= link_to "いいえ", root_path

処理の流れ

読めば分かると思うが、

  1. 何らかの商品ページにアクセス
  2. cookies[:over18] を確認し、yes でなければ
    1. cookies[:original_url] に移動先ページを保持しておき、
    2. 年齢認証ページにリダイレクト
  3. 年齢認証ページで yes を選んだら verified に移動
    1. cookies[:over18]yes を設定し、
    2. cookies[:original_url] にリダイレクト
  4. 以降は cookies[:over18]yes のため、年齢認証はスキップされる

という感じ。

これの良い(楽な)点は、「POST でデータを受け取ったりする必要が無い」というところ。ダメな点は「簡単に嘘を付ける」というところ。

より厳密にやるなら、「ユーザーに誕生日を入力」させて、「表示時に年齢計算を行って判断」という感じの方が良いと思う。
※「ユーザーに誕生日を入力」は、誕生日入力フォームだったり、そもそもユーザー登録だったり。

まとめ

  • cookie に「年齢認証結果」と「本来表示しようとしていたページ(URL)」を保持すると OK
  • 「年齢認証結果」がなければ、「本来表示しようとしていたページ(URL)」を保持しつつ、年齢認証ページにリダイレクト
  • 年齢認証で Yes が選ばれたら、「年齢認証結果」を保持して、「本来表示しようとしていたページ(URL)」にリダイレクト

その他・メモ

ちなみに年齢計算するなら、以下のような感じ(と思っている)。

1
2
3
4
5
6
def over18?
# 年月日はユーザー入力したものを利用
birthday = Time.zone.parse("1995-01-23")
# 「誕生日から18年後」が「本日」より過去かどうかで判断
Time.zone.now() > birthday.since(18.years)
end

参考文献

関連記事