はじめに
自己紹介
未経験からWEB系エンジニアへの転職を目指している者です。現在はRuby on Railsを学習中です。
この記事を書いたきっかけ
現在、プログラミング学習コミュニティでモブプロの取り組みに参加しており、Railsを使って簡易的なURL短縮サービスを実装しています。
その中で、表題のエラーに遭遇したので備忘録として対処法をまとめました。
動作環境
- ruby 3.2.2
- rails 7.1.3
エラーの発生箇所
UrlsControllerの概要
- params[:digest]で短縮urlで受け取る
- Urlsテーブルを検索して短縮urlと紐づく、オリジナルurlを取得する
- オリジナルurlにリダイレクトさせる
Urlsテーブル
- オリジナルURLとそれに対応する短縮URLを管理し、作成日時と更新日時を追跡できる
コード
urls_controller
class UrlsController < ApplicationController
def jump
url = Url.find_by(digest: params[:digest])&.original
if url.nil?
render json: {}, status: 404
else
redirect_to url, status: 301
end
end
redirect_to url, status: 301
の行でエラーが発生しました。
エラーの調査
ActionController::Redirecting::UnsafeRedirectError
についてRailsガイドで調べてみると以下のことがわかりました。
Railsガイド | config.action_controller
- Action Controllerの構成を設定するための構成オプションに
config.action_controller
があり、その設定項目の一つとしてraise_on_open_redirects
がある -
raise_on_open_redirects
のデフォルトの設定では、外部ホストを含むURLがredirect_to
メソッドに渡されるとActionController::Redirecting::UnsafeRedirectError
が発生する
今回の場合、短縮URLのリダイレクト先が外部ホストであるyahooのトップページとなっていたためエラーが発生したようです。
エラーの対処方法
Railsガイドによると、外部ホストを含むURLの呼び出しを許可する場合はredirect_to
メソッドの呼び出しにallow_other_host: true
オプションを追加する必要があるとのことでした。
修正後のコード
urls_controller
class UrlsController < ApplicationController
def jump
url = Url.find_by(digest: params[:digest])&.original
if url.nil?
render json: {}, status: 404
else
# `allow_other_host: true`オプションを追加
redirect_to url, allow_other_host: true, status: 301
end
end