Ruby On Rails - ActionController::InvalidAuthenticityToken
포스팅 시간 기준 아래 버전들로 테스트 하였습니다.
in Gemfile
ruby '2.6.5'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.4'
Issue
Ruby On Rails 튜토리얼을 따라 하던 중 Authentication 관련 문제가 발생하여 정리해 보았습니다.
무료강의 튜토리얼 한눈에읽는루비온레일즈 를 따라하던 중에
위와 같은 에러가 발생합니다.
CSRF 공격을 막기위한 CSRF 토큰이 Invalid 하다는 내용입니다.
간략하게 CSRF 토큰은 서버에 저장된 토큰과 사용자가 전달하는 토큰을 비교하여 일치해야만 결과를 처리합니다.
Ruby On Rails 프레임워크가 그 과정을 도와주게 되는데 이 때 여러가지 이유로 위와 같은 문제가 발생합니다.
사용자 입력에 토큰이 없는경우
간단합니다.
form 태그 안에 authenticity_token을 넣어주면 됩니다.
폼헬퍼 사용 (form_tag)
<%= form_tag "/posts/create", method: :post do %>
<input type="text" name="data">
<button>
제출
</button>
<% end %>
폼에 직접 입력
<form action="/home/next" method="GET">
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
<input type="text" name="data">
<button>
제출
</button>
</form>
동적 폼에 사용 시
<head>
<%= csrf_meta_tags %>
</head>
반대로 사용자 토큰을 처리 못하는 경우
CSRF 토큰을 처리 못하는 경우거나, 아직 세션을 만들지 않은 페이지인 경우는
반대로 CSRF 토큰을 처리 못하도록 Controller에 명시 해야합니다.
protect_from_forgery unless: -> { request.format.json? }
에러가 발생한 controller (ex. posts_controller.rb)에 해당 구문을 입력해서 예외처리 합니다.
class PostsController < ApplicationController
protect_from_forgery unless: -> { request.format.json? }
def index
@posts = Post.all
end
def new
end
def create
Post.create(title: params[:title], content: params[:content])
redirect_to "/posts/index"
end
def show
end
end
결론
저 같은 경우는 CSRF 토큰을 받아 줄 수 없는 튜토리얼이었기 때문에
2번째 경우에 해당하여 Controller를 수정하여 에러를 해결했습니다.
다만 위와 같이 중요하지 않은 페이지에서만 예외를 둬야하기 때문에 사용 시 유의해야합니다.
Leave a comment