Skip to content

Instantly share code, notes, and snippets.

@Ross-Hunter
Last active December 12, 2019 06:28
Show Gist options
  • Save Ross-Hunter/885ff2bccf6b3f68be0e7b9dad361f00 to your computer and use it in GitHub Desktop.
Save Ross-Hunter/885ff2bccf6b3f68be0e7b9dad361f00 to your computer and use it in GitHub Desktop.
# We mix this in to our controllers
module Authenticatable
extend ActiveSupport::Concern
included do
before_action :authenticate_user!
end
protected
def authenticate_user!
http_token = header_auth_token || params[:'auth-token']
decoded = TokenService.decode http_token
@current_user = User.find decoded&.dig(:user_id)
rescue ActiveRecord::RecordNotFound
raise Exceptions::TokenError, 'User not found'
end
private
def header_auth_token
request.headers['HTTP_AUTHORIZATION']&.split(' ')&.last
end
end
# This is the service that actually does the JWT stuff
class TokenService
def self.encode payload
payload[:exp] ||= 24.hours.from_now.to_i
JWT.encode(payload, secret, 'HS256')
rescue
raise Exceptions::TokenError, "Could not encode"
end
def self.decode token
HashWithIndifferentAccess.new(JWT.decode(token, secret, true, algorithm: 'HS256')[0])
rescue
raise Exceptions::TokenError, "Could not decode"
end
def self.secret
Rails.application.secrets.secret_key_base
end
end
# This is what my base controller looks like
class Api::V2::ResourceController < JSONAPI::ResourceController
include Pundit::ResourceController
include Authenticatable
before_action :set_default_response_format
skip_before_action :verify_authenticity_token
respond_to :json
def set_default_response_format
request.format ||= 'application/vnd.api+json'
end
end
# This is what the auth controller looks like, that hands out tokens to clients
class Api::V2::AuthenticationController < ActionController::Base
protect_from_forgery
include ErrorHandler
before_action :set_default_response_format
def authenticate
u = User.find_for_database_authentication(email: auth_params[:email])
@user = u if u&.valid_password?(auth_params[:password])
@token = TokenService.encode(user_id: @user.id) if @user
if @token
render json: { token: @token }
else
render json: { error: 'no way man' }, status: :unauthorized
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment