With third party clients connecting to your service you may find that the assumptions or opinions of a typical rails application are not robust enough. We'll run through some key considerations when building an API that will be consumed by a mobile app.
37. JWTs are self contained
so the server can confirm
the user is authenticated
by verifying the signature.
This is similar to how rails secures cookies...
40. module Devise
module Strategies
class JsonWebToken < Base
def valid?
!request.headers['Authorization'].nil?
end
def authenticate!
if claims and user = User.find_by_id(claims.fetch('user_id'))
success! user
else
fail!
end
end
private
def claims
auth_header = request.headers['Authorization'] and
token = auth_header.split(' ').last and
::JsonWebToken.decode(token)
rescue
nil
...
end
Determines whether or
not the strategy should
be ignored...
Provides the current_user
41. http://zacstewart.com/2015/05/14/using-json-web-tokens-to-authenticate-javascript-front-ends-on-rails.html
JWT + Devise Tutorials
JWT via Warden Strategy by Zac Stewart:
I prefer this method over my own tutorial as I find the Warden strategy to
be more elegant than additional controller logic.
https://github.com/jimjeffers/rails-devise-cors-jwt-example
https://www.youtube.com/watch?v=_CAq-F2icp4
Rails + Devise + CORS + JWT Example & Screencast:
This is an example I put together for a client last year. The screencast got quite
a bit of views and the example project may help you.
43. Knock
Seamless JWT authentication for Rails API
class User < ActiveRecord::Base
has_secure_password
end
Works with any model that
has an authenticate method
Like the one rails provides via has_secure_password...
https://github.com/nsarno/knock#knock
44. Knock
Seamless JWT authentication for Rails API
class ApplicationController < ActionController::API
include Knock::Authenticable
end
class SecuredController < ApplicationController
before_action :authenticate_user
def index
# etc...
end
end
https://github.com/nsarno/knock#knock
45. JWT Works Within OAuth
but Doesn’t Replace it.
http://www.seedbox.com/en/blog/2015/06/05/oauth-2-vs-json-web-tokens-comment-securiser-un-api/
Check out this article explaining JWT vs. OAuth:
What about OAuth?
68. Namespace Your Controllers
module V1
class ArticlesController < ApplicationController
def index
articles = Article.trendy
respond_to do |format|
format.json do
render json: articles
end
end
end
end
end
Just Wrap’em in a Module!
69. Use a Route Constraint
This constraint parses the version from an HTTP Header.
class ApiConstraint
attr_reader :version
def initialize(options)
@version = options.fetch(:version)
end
def matches?(request)
request.headers.fetch(:accept).include?("version=#{version}")
end
end
70. Scope Your Routes
See the full tutorial on how to do this via Big Nerd Ranch:
https://www.bignerdranch.com/blog/adding-versions-rails-api/
Rails.application.routes.draw do
scope module: :v1, constraints: ApiConstraint.new(version: 1) do
resources :articles, only: :index
end
scope module: :v2, constraints: ApiConstraint.new(version: 2) do
resources :articles, only: :index
end
end
74. Has its Own DSL
module Twitter
class Grape < Grape::API
version 'v1', using: :header, vendor: 'twitter'
format :json
prefix :api
resource :statuses do
desc 'Return a public timeline'
get :public_timeline do
Status.limit(20)
end
end
76. Grape solves a lot of problems
specific to building an API
that Rails does not and
perhaps is never meant to
[Rails is a web application framework]
87. Supply the Build & Platform
on All Requests
$ curl -H “X-API-Client: iOS_457”
http://localhost:3000/api/articles
88. Patch the Emergency
module Twitter
class Grape < Grape::API
...
helpers do
def issue_119?
headers[”X-API-Client”] == “iOS_457”
end
end
resource :statuses do
desc 'Return a public timeline'
get :public_timeline do
return fix_for_119 if issue_119?
Status.limit(20)
end
end
96. Your Mobile Client Knows What
Timezone Your User is in. Let
it Convert UTC to Local Time.
97. Ruby is too Convenient!
Which of the Following Should You
Use to Query Dates on the Server?
Date.today Time.current
system time application time
https://robots.thoughtbot.com/its-about-time-zones