add jwt authentication on graphql controller

This commit is contained in:
João Geonizeli
2021-08-04 18:49:11 -03:00
parent 64a7fc7da9
commit a755945c61
7 changed files with 78 additions and 11 deletions

View File

@@ -15,12 +15,12 @@ gem "webpacker", "~> 5.0"
gem "bootsnap", ">= 1.4.4", require: false gem "bootsnap", ">= 1.4.4", require: false
gem "devise" gem "devise"
gem "devise-bootstrap-views", "~> 1.0" gem "devise-bootstrap-views"
gem "devise-i18n" gem "devise-i18n"
gem "administrate" gem "administrate"
gem "graphql" gem "graphql"
gem "tailwindcss-rails" gem "tailwindcss-rails"
gem "httparty"
group :development, :test do group :development, :test do
gem "dotenv-rails" gem "dotenv-rails"

View File

@@ -113,6 +113,9 @@ GEM
graphql (1.12.14) graphql (1.12.14)
graphql_playground-rails (2.1.0) graphql_playground-rails (2.1.0)
rails (>= 5.1.0) rails (>= 5.1.0)
httparty (0.18.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.8.10) i18n (1.8.10)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
jbuilder (2.11.2) jbuilder (2.11.2)
@@ -143,12 +146,16 @@ GEM
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
marcel (1.0.1) marcel (1.0.1)
method_source (1.0.0) method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0704)
mini_mime (1.1.0) mini_mime (1.1.0)
mini_portile2 (2.6.1) mini_portile2 (2.6.1)
minitest (5.14.4) minitest (5.14.4)
momentjs-rails (2.20.1) momentjs-rails (2.20.1)
railties (>= 3.1) railties (>= 3.1)
msgpack (1.4.2) msgpack (1.4.2)
multi_xml (0.6.0)
nio4r (2.5.8) nio4r (2.5.8)
nokogiri (1.12.1) nokogiri (1.12.1)
mini_portile2 (~> 2.6.1) mini_portile2 (~> 2.6.1)
@@ -304,11 +311,12 @@ DEPENDENCIES
bootsnap (>= 1.4.4) bootsnap (>= 1.4.4)
capybara capybara
devise devise
devise-bootstrap-views (~> 1.0) devise-bootstrap-views
devise-i18n devise-i18n
dotenv-rails dotenv-rails
graphql graphql
graphql_playground-rails graphql_playground-rails
httparty
jbuilder (~> 2.7) jbuilder (~> 2.7)
listen (~> 3.3) listen (~> 3.3)
pg (~> 1.1) pg (~> 1.1)

View File

@@ -0,0 +1,12 @@
# frozen_string_literal: true
module Authenticable
def current_auth
@current_auth ||= Auth::Authenticate.new(bearer_token).profile
end
def bearer_token
pattern = /^Bearer /
header = request.headers["Authorization"]
header.gsub(pattern, "") if header&.match(pattern)
end
end

View File

@@ -1,17 +1,16 @@
# frozen_string_literal: true # frozen_string_literal: true
class GraphqlController < ApplicationController class GraphqlController < ApplicationController
# If accessing from outside this domain, nullify the session include Authenticable
# This allows for outside API access while preventing CSRF attacks,
# but you'll have to authenticate your user separately protect_from_forgery with: :null_session
# protect_from_forgery with: :null_session
def execute def execute
variables = prepare_variables(params[:variables]) variables = prepare_variables(params[:variables])
query = params[:query] query = params[:query]
operation_name = params[:operationName] operation_name = params[:operationName]
context = { context = {
# Query context goes here, for example: current_user: current_admin_user, # || current_auth.current_user,
current_user: current_admin_user, current_auth: current_auth,
} }
result = XStakeSchema.execute(query, variables: variables, context: context, operation_name: operation_name) result = XStakeSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
render(json: result) render(json: result)
@@ -22,7 +21,6 @@ class GraphqlController < ApplicationController
private private
# Handle variables in form data, JSON body, or a blank value
def prepare_variables(variables_param) def prepare_variables(variables_param)
case variables_param case variables_param
when String when String
@@ -34,7 +32,7 @@ class GraphqlController < ApplicationController
when Hash when Hash
variables_param variables_param
when ActionController::Parameters when ActionController::Parameters
variables_param.to_unsafe_hash # GraphQL-Ruby will validate name and type of incoming variables. variables_param.to_unsafe_hash
when nil when nil
{} {}
else else

View File

@@ -0,0 +1,20 @@
# frozen_string_literal: true
module Auth
class Auth0Client
class << self
def find_profile(token)
Profile.new(user_profile_attributes(token))
end
def user_profile_attributes(token)
HTTParty.get(
"https://#{ENV["AUTH_DOMAIN"]}/userinfo",
headers: {
"Content-Type" => "application/json",
"Authorization": "Bearer #{token}",
}
).with_indifferent_access
end
end
end
end

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: true
module Auth
class Authenticate
attr_reader :jwt_token
def initialize(jwt_token)
@jwt_token = jwt_token
end
def profile
Auth0Client.find_profile(jwt_token)
end
end
end

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
module Auth
class Profile
attr_reader :id, :email
def initialize(attributes)
@id = attributes[:sub]
@email = attributes[:email]
end
def customer
@customer ||= Customer.find_by(email: email, auth_id: id)
end
end
end