Skip to content

Instantly share code, notes, and snippets.

@neomadara
Forked from goncalvesjoao/Gemfile
Created April 20, 2018 11:50
Show Gist options
  • Save neomadara/aac6c96cc5cf392140f9b77fe2f8ff03 to your computer and use it in GitHub Desktop.
Save neomadara/aac6c96cc5cf392140f9b77fe2f8ff03 to your computer and use it in GitHub Desktop.
Changes you need to make in order to make Devise use JWT Header Authentication
# Add somewhere to your Devise configuration
# "config/initializers/devise.rb"
Devise.setup do |config|
# ...
config.warden do |manager|
# Registering your new Strategy
manager.strategies.add(:jwt, Devise::Strategies::JsonWebToken)
# Adding the new JWT Strategy to the top of Warden's list,
# Scoped by what Devise would scope (typically :user)
manager.default_strategies(scope: :user).unshift :jwt
end
# ...
end
# Add the "https://github.com/jwt/ruby-jwt" gem to your "Gemfile"
gem 'jwt'
# Add the following code to a view
# It will show you an example of how to make a
# curl HTTP request with the proper authentication headers.
# Be sure to actually use a working route and not "http://localhost:3000/api/v1/yada_yada"
<% if user_signed_in? %>
curl -X GET --header 'Authorization: Bearer <%= JWTWrapper.encode({ user_id: current_user.id }) %>' 'http://localhost:3000/api/v1/yada_yada'
<% end %>
# Your actual JWT Strategy
# "config/initializers/core_extensions/devise/strategies/json_web_token.rb"
module Devise
module Strategies
class JsonWebToken < Base
def valid?
bearer_header.present?
end
def authenticate!
return if no_claims_or_no_claimed_user_id
success! User.find_by_id claims['user_id']
end
protected
def bearer_header
request.headers['Authorization']&.to_s
end
def no_claims_or_no_claimed_user_id
!claims || !claims.has_key?('user_id')
end
private
def claims
strategy, token = bearer_header.split(' ')
return nil if (strategy || '').downcase != 'bearer'
JWTWrapper.decode(token) rescue nil
end
end
end
end
# Helper module for you to use on your app and in your Strategy
# Don't add "Helper" to its name and rails won't load it has a view helper module.
# "app/helpers/jwt_wrapper.rb"
module JWTWrapper
extend self
def encode(payload, expiration = nil)
expiration ||= Rails.application.secrets.jwt_expiration_hours
payload = payload.dup
payload['exp'] = expiration.to_i.hours.from_now.to_i
JWT.encode payload, Rails.application.secrets.jwt_secret
end
def decode(token)
begin
decoded_token = JWT.decode token, Rails.application.secrets.jwt_secret
decoded_token.first
rescue
nil
end
end
end
# Add somewhere to your secrets yml
# "config/secrets.yml"
development:
# ...
jwt_secret: 'super random key'
jwt_expiration_hours: 24
# ...
production:
# ...
jwt_secret: 'even more super random key'
jwt_expiration_hours: 6
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment