To implement the suggested design to protect your Rails API from CSRF attacks, follow these steps:
Enable CSRF protection in the application_controller.rb file:
class ApplicationController < ActionController::API
protect_from_forgery with: :exception
end
Implement an endpoint in the Rails API to generate and return the CSRF token:
First, create a new controller:
# app/controllers/csrf_controller.rb
class CsrfController < ApplicationController
skip_before_action :verify_authenticity_token
def token
render json: { csrf_token: form_authenticity_token }
end
end
Next, add a route for the new endpoint in config/routes.rb:
Rails.application.routes.draw do
# Add this line for the new CSRF token endpoint
get 'csrf/token', to: 'csrf#token'
# Other routes...
end
Update your React application to fetch the CSRF token when it loads and include the token in the request headers:
First, fetch the CSRF token when the React application loads and store it in the application state or a context. For example, if you are using React Hooks:
// App.js
import React, { useState, useEffect } from 'react';
function App() {
const [csrfToken, setCsrfToken] = useState(null);
useEffect(() => {
async function fetchCsrfToken() {
const response = await fetch('/csrf/token');
const data = await response.json();
setCsrfToken(data.csrf_token);
}
fetchCsrfToken();
}, []);
return (
<div className="App">
{/* Your application components */}
</div>
);
}
export default App;
Next, include the fetched CSRF token in the request headers when making API calls from the React application. If you are using fetch:
async function makeApiRequest(url, method = 'GET', body = null) {
const headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('X-CSRF-Token', csrfToken); // Add the CSRF token to the headers
const requestOptions = {
method: method,
headers: headers,
credentials: 'include',
};
if (body) {
requestOptions.body = JSON.stringify(body);
}
const response = await fetch(url, requestOptions);
return response.json();
}
This implementation ensures that the Rails API is protected from CSRF attacks while maintaining compatibility with the React frontend. Remember to regularly assess and monitor the application's security, especially as new features and endpoints are added.