GorillaProxy
Configurable Rails Engine for proxying API requests to the Gorilla API.
Installation
Add it to the Gemfile using Gorilla's private gem source:
source 'https://[email protected]/gorilla/' do
gem 'gorilla_proxy'
end
Then mount it in the client Rails application:
Rails.application.routes.draw do
mount GorillaProxy::Engine => '/'
end
Configuration
Setup Application Keys
By default, the proxy will look for the following environment variables:
GORILLA_APP_KEY- The application's keyGORILLA_APP_SECRET- The application's secret
You should probably just put those values in the ENV, but, if you have to do
it manually, you can do so in an initializer:
GorillaProxy.configure do |c|
c.app_key = 'app-key-which-not-stored-in-the-repo'
c.app_secret = 'app-secret-which-not-stored-in-the-repo'
end
CSRF Protection
One of the benefits of proxying the API is the added advantage of CSRF protection natively with Rails. Mainting CSRF protected connections is really easy, and there are only a few steps you need to follow.
Initialization - When the user visits the page and we load the client layout, make sure the CSRF token is stored in the typical
metatag attribute in thehead.<%= csrf_meta_tags %>AJAX Requests and
X-CSRF-Token- Take the value of that tag and send it along with any AJAX requests in theX-CSRF-Tokenheader. Rails will handle validating the token.Caching the new token - Your AJAX request handler should also look for a
X-CSRF-Tokenin the response. Store that new token so it can be re-used in step #2.
Here's an example:
// On Application load
window.csrfToken = $('meta[name="csrf-token"]').attr('content');
// Set an ajax prefilter for the CSRF Token
$.ajaxPrefilter(function(options, originalOptions, xhr) {
xhr.setRequestHeader('X-CSRF-Token', window.csrfToken);
});
// Set an ajax completion handler on the document
$(document).ajaxComplete(function(event, xhr, settings) {
var newToken = xhr.getResponseHeader('X-CSRF-Token');
if (newToken) { window.csrfToken = newToken; }
});
Routes and Proxying
Proxying is handled by directly processing relative endpoints. For example, a call to the app's backend like so:
PUT /api/forms/1
Host: app.gorilla.io
{"name": 'New form name'}
Get's translated into:
PUT /forms/1
Content-Type: application/json
Accept: application/vnd.gorilla.v1+json
Host: api.gorilla.io
{"name": 'New form name'}
The response from the call to the app's backend will mirror the response from Gorilla API exactly.
List of Routes
| Proxy Route | App Route | Authentication |
|---|---|---|
/api/apps/:path |
api.gorilla.io/apps/:path |
Application Signature |
/api/:path |
api.gorilla.io/:path |
Bearer Token |
/auth/login |
api.gorilla.io/apps/tokens/authorize |
Application Signature |
/auth/logout |
api.gorilla.io/apps/tokens/revoke |
Application Signature |
/auth/refresh |
api.gorilla.io/apps/tokens/refresh |
Application Signature |