Guardian.resource_from_claims/1 function always returns nil instead of user

Hi,

I am new to elixir. I have a web app in elixir which is not done by me. I am finding it difficult to understand the code. When ever I try to access an api which requires authentication, it always return “no authorization”.

I am not able to call any function that is included within plug MyApiWebPlug.Auth when action in [update_profile, :get_myprofile, .......]

All the function fails and response with no authorization . since that’s the message in halt_request

After signin in, I got a token and I am passing the token as authorization along with all the api calls.

but they all fails at this line MyApi.Guardian.resource_from_claims. It returns nil

if it helps, I am posting the Plug.Conn module.

defmodule MyApiWeb.Plug.Auth do
  @moduledoc """
  This Plug performs authentication.
  """

  import Plug.Conn

  def init(default), do: default

  def call(conn, _) do
    case Enum.find(conn.req_headers, &elem(&1, 0) == "authorization") do
      {_, token} ->

        case MyApi.Guardian.decode_and_verify(token, %{"typ" => "access"}) do
          {:ok, claims} ->

            case Guardian.DB.on_verify(claims, token) do
              {:ok, {claims, _}} ->

                user =
                  claims
                  |> MyApi.Guardian.resource_from_claims
                  |> elem(1)

                if user == nil,
                  do: halt_request(conn),
                  else: conn |> assign(:user, user)

              {:error, _} -> halt_request(conn)
            end

          {:error, _} -> halt_request(conn)
        end

      nil -> halt_request(conn)
    end
  end

  def halt_request(conn) do
    conn
      |> put_resp_content_type("application/json")
      |> send_resp(403, Poison.encode!(%{message: "no authorization"}))
      |> halt
  end

end

It is the same code as in your previous question…

The problem is probably not with the application, but with the way You pass the authorization token.

You could put some log to see what kind of token You receive.

There is not enough information to debug your problem.

I signed in and received a token. With that i tried to access http://localhost:4000/api/auth_test

These are some logs while entering the above mentioned code.

following is the value inside req_headers printed right after def call(conn, _) do

[{"authorization", "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpa2tpX2FwaSIsImV4cCI6MTU5MDA1ODcyNywiaWF0IjoxNTkwMDU1MTI3LCJpc3MiOiJpa2tpX2FwaSIsImp0aSI6IjUzZDVhNDk4LWViYTMtNDg0OS04MjBhLTFhMjA0YjA0ZWMzMyIsIm5iZiI6MTU5MDA1NTEyNiwic3ViIjoiIiwidHlwIjoiYWNjZXNzIn0.xx_C5tpI4GuuTLFOgxHVTDuwXy-QxFuhpUQVl1X4jBgqfDX2b3MNmFcqn50T2gHyfl0L9qZ8kE8oCmFMbkHQEA"}, {"content-type", "application/json"}, {"user-agent", "PostmanRuntime/7.24.1"}, {"accept", "*/*"}, {"cache-control", "no-cache"}, {"postman-token", "638a87d6-cf0d-44ca-ab7e-b2d91560bb99"}, {"host", "localhost:4000"}, {"accept-encoding", "gzip, deflate, br"}, {"connection", "keep-alive"}]

I am able to access token variable after the line {_, token} and the MyApi.Guardian.decode_and_verify(token, %{"typ" => "access"}) prints the following

{:ok, %{"aud" => "my_api", "exp" => 1590058727, "iat" => 1590055127, "iss" => "my_api", "jti" => "53d5a498-eba3-4849-820a-1a204b04ec33", "nbf" => 1590055126, "sub" => "", "typ" => "access"}}

In this sub is blank. Is that the reason?

Following is the content inside claims variable

%{"aud" => "my_api", "exp" => 1590058727, "iat" => 1590055127, "iss" => "my_api", "jti" => "53d5a498-eba3-4849-820a-1a204b04ec33", "nbf" => 1590055126, "sub" => "", "typ" => "access"}

Guardian.DB.on_verify(claims, token) prints the following

{:ok, {%{"aud" => "my_api", "exp" => 1590058727, "iat" => 1590055127, "iss" => "my_api", "jti" => "53d5a498-eba3-4849-820a-1a204b04ec33", "nbf" => 1590055126, "sub" => "", "typ" => "access"}, "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpa2tpX2FwaSIsImV4cCI6MTU5MDA1ODcyNywiaWF0IjoxNTkwMDU1MTI3LCJpc3MiOiJpa2tpX2FwaSIsImp0aSI6IjUzZDVhNDk4LWViYTMtNDg0OS04MjBhLTFhMjA0YjA0ZWMzMyIsIm5iZiI6MTU5MDA1NTEyNiwic3ViIjoiIiwidHlwIjoiYWNjZXNzIn0.xx_C5tpI4GuuTLFOgxHVTDuwXy-QxFuhpUQVl1X4jBgqfDX2b3MNmFcqn50T2gHyfl0L9qZ8kE8oCmFMbkHQEA"}}

and finally MyApi.Guardian.resource_from_claims(claims)} prints as following

{:ok, nil}

Is this of any help?

Hi,
can you please tell me what might be the reason conn.assigns.user.id is empty even after logged in

It aslwas return %{}

I am not using Guardian, I have switched to Phoenix Token.

Like this it’s hard to tell, but it would be nice to see how the token is signed.

Usually, this code would be near the new action of the sign in controller.

This module contains the signin function
During sigin its the second function that gets executed

defmodule MyApiWeb.UserController do
  @moduledoc """
  This is the controller of the resource related to the users.
  """

  use MyApiWeb, :controller
  alias MyApi.Account
  alias MyApi.Email
  alias MyApi.Utils

  action_fallback MyApiWeb.FallbackController

  plug MyApiWeb.Plug.Auth when action in [:update_profile, :get_myprofile, :change_password, :update_mailaddress, :signup]
  plug MyApiWeb.Plug.RateLimit when action in [:update_profile, :get_myprofile, :change_password, :update_mailaddress]

  def verify_mailaddress(conn, params) do
    source_service = conn |> MyApi.Utils.source_service?

    resp =
      params
      |> Map.put("source_service", source_service)
      |> Account.verify_mailaddress

    with {:ok, user} <- resp do
      send_register_mail(user)
      json conn, %{message: "Success"}
    end
  end

  def signup(conn, params) do
    with {:ok, _} <- Account.signup(params, conn.assigns.user.id),
      do: json conn, %{message: "Success"}
  end

  def signin(conn, %{"code" => code}) do
    ip =
      to_string(:inet_parse.ntoa(conn.remote_ip))

    case Account.signin_with_code(code) do
      {:ok, token, refresh_token, user} ->
        Task.start_link(fn -> Account.create_login_history(user.id, ip) end)
        json conn, %{user: user, token: token, refresh_token: refresh_token}
      other ->
        other
    end
  end

  def signin(conn, params) do
    ip =
      to_string(:inet_parse.ntoa(conn.remote_ip))

    case Account.signin(params, ip) do
      {:ok, token, refresh_token, user} ->
        Task.start_link(fn -> Account.create_login_history(user.id, ip) end)
        json conn, %{user: user, token: token, refresh_token: refresh_token}
      other ->
        other
    end
  end

  def refresh(conn, %{"refresh_token" => refresh_token}) do
    with {:ok, access_token, refresh_token} <- MyApi.Guardian.refresh_token(refresh_token),
      do: json conn, %{token: access_token, refresh_token: refresh_token}
  end

  def refresh(_, _) do
    {:error, "No token provided"}
  end

  def update_profile(conn, params) do
    params |> Account.edit_profile(conn.assigns.user)
  end

  def update_mailaddress(conn, %{"mailaddress" => _} = params) do
    with {:ok, user} <- Account.update_mailaddress(params, conn.assigns.user.id) do
      send_verify_mailaddress_mail(user)
      json conn, %{message: "Success"}
    end
  end

  def update_mailaddress(_, _), do: {:error, :bad_request}

  def get_profile(conn, %{"user_id" => user_id} = _params) do

    resp =
      user_id
      |> Account.get_profile

    with {:ok, user} <- resp,
      do: json conn, %{user: user}
  end

  def get_myprofile(conn, _params) do

    resp =
      conn.assigns.user.id
      |> Account.get_profile

    with {:ok, user} <- resp,
      do: json conn, %{user: user}
  end

  def change_password(conn, %{"current_password" => cp, "new_password" => np}) do
    with {:ok, _} <- Account.change_password(conn.assigns.user.id, cp, np),
      do: json conn, %{message: "Success"}
  end

  def change_password(_, _), do: {:error, :bad_request}

  def generate_reset_code(conn, %{"mailaddress" => mailaddress}) do
    case Account.generate_reset_code(mailaddress) do
      {:ok, resp} ->
        send_reset_mail(resp, mailaddress)
        json conn, %{message: "Success"}
      {:error, err} ->
        {:error, err}
    end
  end

  def generate_reset_code(_, _), do: {:error, :bad_request}

  def reset_password(conn, %{"code" => code, "new_password" => np}) do
    with {:ok, _} <- Account.reset_password(code, np),
      do: json conn, %{message: "Success"}
  end

  def reset_password(_, _), do: {:error, :bad_request}

  defp send_register_mail(user) do
    user.activate_code
    |> Email.register_mail(user.mailaddress)
  end

  defp send_reset_mail(%MyApi.Account.ResetCode{} = reset_code, mailaddress) do
    "#{Utils.fetch_my_url}/password-reset/#{reset_code.code}"
    |> Email.password_reset_mail(mailaddress)
  end

  defp send_verify_mailaddress_mail(user) do
    user.activate_code
    |> Email.verify_mailaddress_mail(user.mailaddress)
  end
end

Here is the Account module

defmodule MyApi.Account do
  @moduledoc """
  The Account context.
  """

  @type query :: Ecto.Query.t() | MyApi.Account.User
  @type doctor_params :: map()
  @type user :: %MyApi.Account.User{}
  @type users :: [user()]
  @type reset_code :: %MyApi.Account.ResetCode{}
  @type offset :: number() | nil
  @type limit :: number() | nil

  import Ecto.Query, warn: false

  alias Ecto.Multi

  alias MyApi.{Repo, Utils, Stripe, Paginator, Email}

  alias MyApi.Account.User
  alias MyApi.Account.DoctorProfile
  alias MyApi.Account.DoctorTreatmentRelationship
  alias MyApi.Account.ResetCode
  alias MyApi.Account.LoginHistory
  alias MyApi.Account.LoginCode
  alias MyApi.Data.TreatmentCategories

  def verify_mailaddress(params) do
    %User{}
    |> User.verify_mailaddress_changeset(params)
    |> Repo.insert()
  end

  def signup(%{"is_doctor" => true} = params, user_id) do
    with {:ok, user} <- get_user(user_id),
      {:ok, resp} <- user |> create_doctor(params) |> Repo.transaction(),
      do: get_profile(resp.user.id)
  end

  def signup(%{"is_doctor" => false} = params, user_id) do
    with {:ok, user} <- get_user(user_id) do
      user
      |> User.signup_user_changeset(params)
      |> Repo.update()
    end
  end

  def signup(_) do
    {:error, %{errors: ["パラメーターが不正です"]}}
  end

  defp get_user(user_id) do
    case User |> Repo.get(user_id) do
      nil -> {:not_found_resource}
      user -> {:ok, user}
    end
  end

  def activate(activate_code) do
    match_user = User
      |> Repo.get_by(activate_code: activate_code)

    case match_user do
      nil ->
        {:error, "activate code is invalid"}
      _ ->
        match_user
          |> Ecto.Changeset.change(is_activated: true)
          |> Repo.update
    end
  end

  def signin(%{"mailaddress" => mailaddress, "password" => password}, ip_address) do
    user =
      User
      |> Repo.get_by(mailaddress: mailaddress)

    valid_res =
      user
      |> valid_signin(password)
      |> check_suspicious_ip(ip_address)

    with {:ok, _} <- valid_res do
      user
      |> Repo.preload(:good_treatments)
      |> MyApi.Guardian.gen_token
    else
      {:error, _, %{type: "SUSPINCIOUS_IP"}} = err ->
        send_login_code(user)
        err
      err ->
        err
    end

  end

  def signin(_, _) do
    {:error, "Invalid params"}
  end

  def signin_with_code(%LoginCode{} = code) do
    case get_user(code.user_id) do
      {:ok, user} ->
        Repo.delete(code)

        user
        |> Repo.preload(:good_treatments)
        |> MyApi.Guardian.gen_token
      _ ->
        {:error, :not_found_resource}
    end
  end

  def signin_with_code(nil) do
    {:error, "Code is invalid.", %{type: "INVALID_CODE"}}
  end

  def signin_with_code(code) do
    before_one_hour =
      Timex.now("Asia/Tokyo")
      |> Timex.shift(hours: -1)
      |> DateTime.truncate(:second)
      |> DateTime.to_naive

    LoginCode
    |> where([c], c.code == ^code)
    |> where([c], c.inserted_at > ^before_one_hour)
    |> order_by(desc: :id)
    |> limit(1)
    |> Repo.one()
    |> signin_with_code()
  end

  defp create_doctor(user, params) do
    changeset = User.signup_doctor_changeset(user, params)

    Multi.new
    |> Multi.update(:user, changeset)
    |> Multi.run(:good_treatments, &(insert_good_treatments(params["good_treatment_ids"], &1.user.id)))
    |> Multi.run(:doctor_profile, &(update_doctor_profile_assoc(%DoctorProfile{}, params["doctor_profile"], &1.user)))
  end

  def edit_profile(params, %{is_doctor: true} = current) do
    resp =
      current
      |> update_doctor_profile(params)
      |> Repo.transaction

    with {:ok, resp} <- resp,
      do: get_profile(resp.user.id)
  end

  def edit_profile(params, %{is_doctor: false} = current) do
    current
    |> User.update_profile_user_changeset(params)
    |> Repo.update
  end

  def edit_profile(_, _) do
    {:error, "Invalid user."}
  end

  def update_mailaddress(params, user_id) do
    case User |> Repo.get(user_id) do
      nil -> {:error, "存在しないユーザーです"}
      user ->
        user
        |> User.update_mailaddress_changeset(params)
        |> Repo.update()
    end
  end

  def get_profile(user_id) do
    user_id = Utils.any_to_integer(user_id)

    user =
      User
      |> preload([:profile_image, :header_image, :good_treatments])
      |> Repo.get(user_id)

    case user do
      nil -> {:not_found_resource}
      _ -> {:ok, user}
    end
  end

  defp send_login_code(user) do
    {:ok, %{code: code}} =
      %LoginCode{}
      |> LoginCode.changeset(%{user_id: user.id})
      |> Repo.insert()

    Task.start_link(fn -> Email.login_code(code, user.mailaddress) end)
  end

  defp check_suspicious_ip({:ok, user}, ip_address) do
    check_suspicious_ip(user, ip_address)
  end

  defp check_suspicious_ip(%{id: user_id} = user, ip_address) do
    history_ips =
      LoginHistory
      |> where([h], h.user_id == ^user_id)
      |> select([h], h.ip_address)
      |> limit(100)
      |> Repo.all

    if Enum.count(history_ips) !== 0 and ip_address not in history_ips,
      do: {:error, "Detected suspincious ip address. check your email.", %{type: "SUSPINCIOUS_IP"}},
      else: {:ok, user}
  end

  defp check_suspicious_ip(resp) do
    resp
  end

  defp valid_signin(%{is_activated: false} = _user, _password) do
    {:error, "Not activated", additional: %{type: "NOT_ACTIVATED"}}
  end

  defp valid_signin(%{is_doctor: true, is_activated_doctor: false} = _user, _password) do
    {:error, "You have not been approved by the administrator yet.", additional: %{type: "NOT_ACTIVATED_DOCTOR"}}
  end

  defp valid_signin(nil, _password) do
    {:error, "Not found user", additional: %{type: "NOT_FOUND"}}
  end

  defp valid_signin(user, password) do
    if check_valid_password(user, password),
      do: {:ok, user},
      else: {:error, "Invalid mailaddress or password", additional: %{type: "INVALID_INFO"}}
  end

  @spec check_valid_password(user(), String.t()) :: boolean()
  defp check_valid_password(user, password) do
    Comeonin.Bcrypt.checkpw(password, user.password)
  end

  defp update_doctor_profile(current, params) do
    changeset =
      current
      |> User.update_profile_doctor_changeset(params)

    Multi.new
    |> Multi.update(:user, changeset)
    |> Multi.run(:good_treatments, fn %{user: user} ->
      if params["good_treatment_ids"],
        do: update_good_treatments(params["good_treatment_ids"], user.id),
        else: {:ok, 0}
    end)
    |> Multi.run(:doctor_profile, &(update_doctor_profile_assoc(&1.user.doctor_profile, params["doctor_profile"], &1.user)))
  end

  defp insert_good_treatments(ids, user_id) do
    treatments =
      ids
      |> TreatmentCategories.filter_treatment_ids
      |> Enum.map(fn(treatment_id) ->
        %{user_id: user_id, treatment_category_id: treatment_id}
        |> Map.put(:inserted_at, Ecto.DateTime.utc)
        |> Map.put(:updated_at, Ecto.DateTime.utc)
      end)

    with {count, _} <- Repo.insert_all(DoctorTreatmentRelationship, treatments),
      do: {:ok, count}
  end

  defp update_good_treatments(ids, user_id) do
    DoctorTreatmentRelationship
    |> where([q], q.user_id == ^user_id)
    |> Repo.delete_all

    insert_good_treatments(ids, user_id)
  end

  defp update_doctor_profile_assoc(struct, params, user) do
    doctor_profile_chageset =
      struct
      |> DoctorProfile.changeset(Map.put(params || %{}, "user_id", user.id))

    assoc_changeset =
      user
      |> Ecto.Changeset.change
      |> Ecto.Changeset.put_embed(:doctor_profile, doctor_profile_chageset)

    assoc_changeset =
      if doctor_profile_chageset.errors != [],
        do: assoc_changeset |> Ecto.Changeset.add_error(:child_invalid, "ドクタープロフィールに未入力項目があります"),
        else: assoc_changeset

    Repo.update assoc_changeset
  end

  # admin
  @spec get_offset_doctors(map()) :: users
  def get_offset_doctors(params) do
    User
    |> get_doctors(params)
  end

  @spec get_not_approve_doctor(map()) :: users
  def get_not_approve_doctor(params) do
    User
    |> where([u], u.is_activated_doctor == false)
    |> get_doctors(params)
  end

  @spec get_already_approve_doctor(map()) :: users
  def get_already_approve_doctor(params) do
    User
    |> where([u], u.is_activated_doctor == true)
    |> get_doctors(params)
  end

  def approve_doctor(user_id) do
    doctor = User |> Repo.get_by([id: user_id, is_doctor: true])

    case doctor do
      nil -> {:not_found_resource}
      %{} ->
        doctor
        |> User.doctor_approve_changeset(%{is_activated_doctor: true})
        |> Repo.update
    end

  end

  @spec search_doctors(map()) :: users
  def search_doctors(%{"doctor" => doctor_params = %{}} = params) do
    User
    |> join(:inner, [u], gt in assoc(u, :good_treatments))
    |> preload([_, gt], [good_treatments: gt])
    |> where_doctors_have_params(doctor_params)
    |> get_doctors(params)
  end

  def search_doctors(_), do: {:error, :bad_request}

  @spec where_doctors_have_params(query, map()) :: query
  defp where_doctors_have_params(query, params) do
    query
    |> where_doctor_have_treatments(params["treatments"])
    |> where_doctor_have_location(params["location"])
  end

  @spec where_doctor_have_treatments(query, list()) :: query
  defp where_doctor_have_treatments(query, nil), do: query

  defp where_doctor_have_treatments(query, treatments) when is_list(treatments) do
    query
    |> where([_, gt], gt.id in ^treatments)
  end

  @spec where_doctor_have_location(query, String.t()) :: query
  defp where_doctor_have_location(query, nil), do: query

  defp where_doctor_have_location(query, location) do
    query
    |> where([], fragment("doctor_profile->>'hospital_location' ILIKE ?",
      ^"%#{location}%"))
  end

  @spec get_random_doctors(limit :: non_neg_integer) :: [%User{}] | no_return
  def get_random_doctors(limit \\ 50)

  def get_random_doctors(nil), do: get_random_doctors

  def get_random_doctors(limit) do
    User
    |> preload(:good_treatments)
    |> where([u], u.is_doctor == true)
    |> order_by(fragment("RANDOM()"))
    |> limit(^limit)
    |> Repo.all()
  end

  @spec get_doctors(query, map()) :: users
  defp get_doctors(query, params) do
    query
    |> where([u], u.is_doctor == true)
    |> order_by(desc: :id)
    |> Paginator.new(params)
  end

  # password
  @spec change_password(integer(), String.t(), String.t()) :: {:ok, user()} | {:error, any()}
  def change_password(user_id, current_password, new_password) do
    user =
      Repo.get(User, user_id)

    case check_valid_password(user, current_password) do
      true ->
        update_password(user, new_password)
      false ->
        {:error, "Password is incorrect"}
    end
  end

  @spec generate_reset_code(String.t()) :: {:ok, reset_code} | {:error, Ecto.Changeset.t()}
  def generate_reset_code(mailaddress) do
    user =
      User
      |> where([u], u.mailaddress == ^mailaddress)
      |> limit(1)
      |> Repo.one

    case user do
      nil ->
        {:error, "Not found user."}
      %User{} ->
        %ResetCode{}
        |> ResetCode.changeset(%{user_id: user.id})
        |> Repo.insert
    end
  end

  @spec reset_password(String.t(), String.t()) :: {:ok, any()} | {:error, any()}
  def reset_password(code, new_password) do
    reset_code =
      ResetCode
      |> where([c], c.code == ^code)
      |> limit(1)
      |> Repo.one
      |> Repo.preload(:user)

    case reset_code do
      nil ->
        {:error, "Code is invalid"}
      %ResetCode{user: user} ->
        update_password_with_code(reset_code, user, new_password)
      _ ->
        {:error, "Not found user"}
    end
  end

  @spec update_password_with_code(reset_code, user, String.t()) :: {:ok, any()} | {:error, any()}
  defp update_password_with_code(%ResetCode{} = reset_code, %User{} = user, new_password) do
    case update_password(user, new_password) do
      {:ok, _} ->
        reset_code
        |> ResetCode.use_changeset(%{is_used: true})
        |> Repo.update
      {:error, err} ->
        {:error, err}
    end
  end

  @spec update_password(user(), String.t()) :: {:ok, user()} | {:error, Ecto.Changeset.t()}
  defp update_password(user, new_password) do
    user
    |> User.update_password_changeset(%{password: new_password})
    |> Repo.update
  end

  # Stripe

  @spec get_stripe_sources(map(), String.t()) :: {:ok, [map()]} | {:error, any()}
  def get_stripe_sources(params, stripe_customer_id) do
    Stripe.get_sources(params, stripe_customer_id)
  end

  @spec create_stripe_source(map(), String.t()) :: {:ok, map()} | {:error, any()}
  def create_stripe_source(params, stripe_customer_id) do
    Stripe.create_source(params, stripe_customer_id)
  end

  @spec update_stripe_source(map(), String.t()) :: {:ok, map()} | {:error, any()}
  def update_stripe_source(params, stripe_customer_id) do
    Stripe.update_source(params, stripe_customer_id)
  end

  @spec delete_stripe_source(map(), String.t()) :: {:ok, map()} | {:error, any()}
  def delete_stripe_source(params, stripe_customer_id) do
    Stripe.delete_source(params, stripe_customer_id)
  end

  @spec create_login_history(number(), String.t()) :: {:ok, map() | {:error, any()}}
  def create_login_history(user_id, ip_address) do
    %LoginHistory{} 
    |> LoginHistory.changeset(%{user_id: user_id, ip_address: ip_address})
    |> Repo.insert
  end

  @spec get_login_histories(number()) :: [%LoginHistory{}]
  def get_login_histories(user_id) do
    LoginHistory
    |> where([lh], lh.user_id == ^user_id)
    |> order_by(desc: :id)
    |> limit(20)
    |> Repo.all()
  end

end

And this is the guardian module defined. It is a separate module defined in the project and it call some functions in the dependency guardian also

defmodule MyApi.Guardian do
  @moduledoc """
  The Guardian module.
  """

  use Guardian, otp_app: :my_api

  alias MyApi.Account.User
  alias MyApi.Repo

  def gen_token(resource) do
    {:ok, token, claims} = resource
      |> __MODULE__.encode_and_sign(%{})
    {:ok, refresh_token, refresh_claims} = resource
      |> __MODULE__.encode_and_sign(%{}, token_type: "refresh")

    {:ok, _} = signin_save(resource, claims, token)
    {:ok, _} = signin_save(resource, refresh_claims, refresh_token)

    {:ok, token, refresh_token, resource}
  end

  def refresh_token(refresh_token) do

    claims = case MyApi.Guardian.decode_and_verify(refresh_token) do
      {:ok, claims} -> claims
      {:error, _} -> nil
    end

    cond do
      claims == nil ->
        {:error, "Not found token"}
      is_verify(claims, refresh_token) == false ->
        {:error, "Invalid token"}
      true ->
        exchange_token(refresh_token)
    end

  end

  def subject_for_token(resource, _) do
    {:ok, to_string(resource.uuid) }
  end

  def resource_from_claims(claims) do

    if Ecto.UUID.dump(claims["sub"]) == :error,
      do: {:ok, nil} ,
      else: {:ok, User |> Repo.get_by(uuid: claims["sub"])}
  end

  defp signin_save(resource, claims, token) do
    with {:ok, _} <- Guardian.DB.after_encode_and_sign(resource, claims["typ"], claims, token) do
      {:ok, token}
    end
  end

  defp token_revoke(claims, token) do
    with {:ok, _} <- Guardian.DB.on_revoke(claims, token) do
      {:ok, claims}
    end
  end

  defp is_verify(claims, refresh_token) do
    case Guardian.DB.on_verify(claims, refresh_token) do
      {:ok, _}    -> true
      {:error, _} -> false
    end
  end

  defp exchange_token(token) do
    case MyApi.Guardian.exchange(token, "refresh", "access") do
      {:ok, {old_token, old_claims}, {new_token, new_claims}} ->

        {:ok, resource} = resource_from_claims(new_claims)

        # save new access token
        {:ok, _} = resource |> signin_save(new_claims, new_token)

        # revoke old refresh token
        {:ok, _} = token_revoke(old_claims, old_token)

        # get new refresh_token
        {:ok, new_refresh_token, new_refresh_claims} = resource
          |> __MODULE__.encode_and_sign(%{}, token_type: "refresh")

        # save new refresh token
        {:ok, _} = resource
          |> signin_save(new_refresh_claims, new_refresh_token)

        {:ok, new_token, new_refresh_token}
      {:error, err} ->
        {:error, err}
    end
  end

end

One more thing in case it helps. dev.secret.exs in config folder is missing. We got this error, so commented the line #import_config "dev.secret.exs" in dev.exs to remove the error.

Hi, I got it working.

The order of signup was different.

First I had to validate my email with Stripe and insert these details to db.

Then with the given activation code, I had to activate my account.

Then with the token received after activation, I can signup that user with password and other details.

Never seen that kind of an order.

The only issue was there was no stripe key. After fixing that it worked.

Thanks for the support. I had no idea what I was doing with this project.