Commit d6354d6

mo <mo.khan@gmail.com>
2018-09-18 21:28:43
introspect revoked tokens.
1 parent a6030bb
Changed files (4)
app
config
environments
spec
app/controllers/tokens_controller.rb
@@ -15,7 +15,11 @@ class TokensController < ApplicationController
 
   def introspect
     claims = Token.claims_for(params[:token], token_type: :any)
-    render json: claims.merge(active: true), status: :ok
+    if revoked_tokens[claims[:jti]]
+      render json: { active: false }, status: :ok
+    else
+      render json: claims.merge(active: true), status: :ok
+    end
   end
 
   private
@@ -77,4 +81,10 @@ class TokensController < ApplicationController
       assertion_grant
     end
   end
+
+  def revoked_tokens
+    Rails.cache.fetch("revoked-tokens", expires_in: 10.minutes) do
+      Hash[Token.revoked.pluck(:uuid).map { |x| [x, true] }]
+    end
+  end
 end
config/environments/test.rb
@@ -46,5 +46,6 @@ Rails.application.configure do
 
   # Raises error for missing translations
   # config.action_view.raise_on_missing_translations = true
+  config.cache_store = :null_store
 end
 Rails.application.default_url_options = { host: 'www.example.com' }
spec/requests/tokens_spec.rb
@@ -258,5 +258,16 @@ RSpec.describe '/tokens' do
       specify { expect(json[:exp]).to eql(token.claims[:exp]) }
       specify { expect(json[:iat]).to eql(token.claims[:iat]) }
     end
+
+    context "when the token is revoked" do
+      let(:token) { create(:access_token, :revoked) }
+
+      before { post '/tokens/introspect', params: { token: token.to_jwt }, headers: headers }
+
+      specify { expect(response).to have_http_status(:ok) }
+      specify { expect(response['Content-Type']).to include('application/json') }
+      let(:json) { JSON.parse(response.body, symbolize_names: true) }
+      specify { expect(json[:active]).to eql(false) }
+    end
   end
 end
spec/factories.rb
@@ -15,6 +15,10 @@ FactoryBot.define do
     factory :refresh_token do
       token_type { :refresh }
     end
+
+    trait :revoked do
+      revoked_at { Time.now }
+    end
   end
 
   factory :authorization do