GuardianDB is an extension to vanilla Guardian that tracks tokens in your
application to prevent playback.

All tokens are stored in the database when initially generated.
After that, each time they are verified, the token is looked up. If present, the
verification continues but if it is not found, the verification is abandoned
with an error response.

    case Guardian.encode_and_sign(resource, type, claims) do
      { :ok, jwt, full_claims } -> # cool
      { :error, :token_storage_failure } -> # this comes from GuardianDb
      { :error, reason } -> # handle failure

    case Guardian.decode_and_verify(jwt) do
      { :ok, claims } -> # stuff with the claims
      { :error, :token_not_found } -> # This comes from GuardianDb
      { :error, reason } -> # something else stopped us from verifying

When you want to revoke a token, call Guardian.revoke!. This is called
automatically by Guardian when using the sign\_out function. But for times when
you're using an API.

    case Guardian.revoke! jwt, claims do
      :ok -> # Great
      { :error, :could_not_revoke_token } -> # Oh no GuardianDb
      { :error, reason } -> # Oh no

To use GuardianDb you'll need to add a migration

    defmodule MyApp.Repo.Migrations.GuardianDb do
      use Ecto.Migration

      def up do
        create table(:guardian_tokens, primary_key: false) do
          add :jti, :string, primary_key: true
          add :aud, :string
          add :iss, :string
          add :sub, :string
          add :exp, :integer
          add :jwt, :text
          add :claims, :text

      def down do
        drop table(:guardian_tokens)

Add this to your configuration:

    config :guardian, Guardian,
           hooks: GuardianDb,

    config :guardian_db, GuardianDb,
           repo: MyApp.Repo

It's a good idea to purge out any stale tokens that have already expired.