Skip to content

Instantly share code, notes, and snippets.

@jdmorlan
Last active March 26, 2016 00:57
Show Gist options
  • Save jdmorlan/fefe12a4d73957fc992e to your computer and use it in GitHub Desktop.
Save jdmorlan/fefe12a4d73957fc992e to your computer and use it in GitHub Desktop.
Setup Json Web Token Authentication in Rails API app
# Located at app/controllers/application_controller.rb
class ApplicationController < ActionController::API
before_action do
@token = Token.new(request.env['auth.token'])
end
def require_token!
error_json = {message: 'No token in HTTP_AUTHORIZATION header'}
render json: error_json, status: 401 unless @token.present?
end
end
# Located at app/auth/auth_token_encoder.rb
module AuthTokenEncoder
def self.encode(payload)
hmac_secret = Rails.application.secrets.secret_key_base
JWT.encode(payload, hmac_secret, 'HS256')
end
end
# Located at app/auth/auth_token_generator.rb
# The payload can be anything you want it to be, but
# the AuthTokenGenerator produces a payload that
# looks like:
# Example Payload
# {
# user: {
# id: 1,
# email: '[email protected]'
# }
# }
module AuthTokenGenerator
def self.generate(user)
payload = {}
payload[:user] = user_payload(user)
AuthTokenEncoder.encode(payload)
end
def self.user_payload(user)
{
id: user.id,
email: user.email
}
end
end
# Read about JSON Web Tokens at http://jwt.io/
# Add gem 'jwt' to your gemfile
# File located at app/middleware/auth_token_decoder.rb
class AuthTokenDecoder
def initialize(application)
@application = application
end
def call(environment)
@environment = environment
set_decoded_auth_token
@application.call(@environment)
end
private
def get_encoded_token
@environment['HTTP_AUTHORIZATION']
end
def get_hmac_secret
Rails.application.secrets.secret_key_base
end
def set_decoded_auth_token
@environment['auth.token'] = decode_token(get_encoded_token)
end
def decode_token(token)
return nil if token.nil?
JWT.decode(token, get_hmac_secret, true, { algorithm: 'HS256' })
end
end
# Need to tell Rails to use the middleware in three places
# config/environments/development.rb
# config/environments/production.rb
# config/environments/test.rb
config.middleware.use AuthTokenDecoder
# Located at models/token.rb
class Token
attr_reader :token
def initialize(decoded_token)
@token = decoded_token
end
def user
user_id = payload[:user][:id]
@user ||= User.find_by(id: user_id)
end
def header
@header ||= @token[:header]
end
def payload
@payload ||= @token[:payload]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment