Rails+React axiosで通信 ~CSRFトークンの設定~

前回RailsとReact間でaxiosを使ってajax通信をしたのですが, GETメソッドは特別な設定なくできました. しかし, POST(GET以外)は設定しないと動かなかったのでそのメモです.

dai7igarashi.hatenablog.com

 

 

CSRFとは

CSRFとは Cross-Site Request Forgeries の略で, ユーザの意図しない動作をさせる攻撃です.

情報処理推進機構:情報セキュリティ:脆弱性関連情報の取扱い:知っていますか?脆弱性 (ぜいじゃくせい)/3. CSRF (クロスサイト・リクエスト・フォージェリ)

 例えば, AさんがあるSNSにログイン中に悪意のあるサイトを見たとします. そして悪意のあるサイトの罠が仕掛けられたリンクをクリックすると, あたかもAさんがリクエストを出したように, 悪意のあるサイトからログイン中のSNSにリクエストが飛びます. すると例えばアカウントを削除されたりなんなり, 色々悪用されてしまうと言ったことが起こります. これがCSRFです.

 

RailsCSRF対策

RailsにはCSRF対策が施されていて, 悪意のあるサイトからのリクエストか, 自分のプログラムからのリクエストか判別できるような仕組みが用意されています. Railsでは, GETリクエストはそこまで破壊的な処理がなされないと考えているのか, 対策なくaxiosで通信できるのですが, POST, PUT, DELETEでは致命的なダメージを与えると考えているらしく, CSRFトークンと呼ばれるパスワードみたいなものの設定が必須になっています.

Rails側で用意されているヘルパーメソッド(form_forとか)にはデフォルトでこのCSRFトークンが設定されているので気にせずPOSTとかできてましたが, フロントエンドとサーバーサイドを分けて通信する場合には意識しなければなりません.

shindolog.hatenablog.com

 

上記サイトによると, 

   検証を通すには「authenticity_token をフォームに埋め込んでおく」

 「X-CSRF-Token をリクエストヘッダーに設定しておく」

らしいです.

で, 今回の場合どうするかというと, rails-ujsというajax通信をよしなに行ってくれるライブラリのcsrfトークンを取得する機能を使って解決します. 具体的には, 

import React from 'react';
import axios from 'axios';
import { csrfToken } from 'rails-ujs';

class MyApp extends React.Component {
constructor(props) {
super(props);

// この記述だけでaxiosでpostが行える.
axios.defaults.headers.common['X-CSRF-Token'] = csrfToken();
}


func1() {
axios.post('/post_url', {
name: 'Tom',
text: 'Hello World!'
})
.then(response => {
console.log(response.data);
})
.catch(err => {
console.log(err);
});
}

これで送れます. コントローラ側ではparamsにjson形式で入っています. 詳しくはbinding.pryすればわかります.

tech.medpeer.co.jp

 

今後

データベース構築かな....... 以外と一番考えなきゃいけないとこな気がします.