ueberauth / guardian

Elixir Authentication
MIT License
3.44k stars 381 forks source link

"message": "no_resource_found" #434

Closed Yamilquery closed 6 years ago

Yamilquery commented 6 years ago

In my router.ex

pipeline :authorized do
    plug :fetch_session
    plug Guardian.Plug.Pipeline, module: Bark.Guardian,
      error_handler: Bark.AuthErrorHandler
    plug Guardian.Plug.VerifySession
    plug Guardian.Plug.LoadResource
    plug Bark.Web.Context
  end

When I make a request I get:

{ "message": "no_resource_found" }

yordis commented 6 years ago

@Yamilquery LoadResource plug is the one that is failing, make sure that your resource_from_claims/1 function from your Guardian module is actually returning {:ok, resource}

But I need more context of your application for be able to help you out.

willsoto commented 6 years ago

I am having the same issue.

As best as I can tell, resource_from_claims/1 is not being called despite it being defined in MyApp.Auth.Guardian module.

here is my pipeline:

defmodule MyApp.Auth.Pipeline do
  @claims %{typ: "access"}

  use Guardian.Plug.Pipeline,
    otp_app: :my_app,
    module: MyApp.Auth.Guardian,
    error_handler: MyApp.Auth.ErrorHandler

  plug(Guardian.Plug.VerifySession, claims: @claims)
  plug(Guardian.Plug.VerifyHeader, claims: @claims)

  plug(Guardian.Plug.LoadResource)
  plug(Guardian.Plug.EnsureAuthenticated)
end

The MyApp.Auth.Guardian module is exactly what is on the README (with slight tweaks to actually get my resource). FWIW, I know subject_for_token/2 is being correctly called and returning the appropriate tuple.

I'm still debugging since I figure it is something I am missing, but it's hard to know what.

EDIT: So I finally got it working using plug(Guardian.Plug.VerifyHeader, claims: @claims, realm: "Bearer") But I couldn't get it working with Guardian.Plug.VerifySession. Not sure why or what I was missing, but hopefully #386 resolves some of the documentation issues with examples.

hassox commented 6 years ago

Can you paste your guardian module please?

willsoto commented 6 years ago
defmodule MyApp.Auth.Guardian do
  require Logger
  use Guardian, otp_app: :my_app

  alias MyApp.Accounts

  def subject_for_token(user, _claims) do
    # You can use any value for the subject of your token but
    # it should be useful in retrieving the resource later, see
    # how it being used on `resource_from_claims/1` function.
    # A unique `id` is a good subject, a non-unique email address
    # is a poor subject.
    sub = to_string(user.membership_id)
    {:ok, sub}
  end

  def resource_from_claims(claims) do
    # Here we'll look up our resource from the claims, the subject can be
    # found in the `"sub"` key. In `above subject_for_token/2` we returned
    # the resource id so here we'll rely on that to look it up.
    membership_id = claims["sub"]

    user = Accounts.get_user!(membership_id)
    {:ok, user}
  end
end

This is basically taken verbatim from the README with the extra functions removed (the compiler was saying that they would never be hit)

hassox commented 6 years ago

In Bark.Web.Context are you able to get the token with MyApp.Auth.Guardian.Plug.current_token(conn)? or the resource with MyApp.Guardian.Plug.current_resource(conn)?

doomspork commented 6 years ago

@willsoto / @Yamilquery are you still experiencing this issue or can this be closed?

willsoto commented 6 years ago

I "fixed" mine by working around it but I don't understand the root cause. It's fine to close and if I ever figure something out I can reopen. Thanks.

On Fri, Jan 19, 2018, 5:07 PM Sean Callan notifications@github.com wrote:

@willsoto https://github.com/willsoto / @Yamilquery https://github.com/yamilquery are you still experiencing this issue or can this be closed?

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/ueberauth/guardian/issues/434#issuecomment-359102936, or mute the thread https://github.com/notifications/unsubscribe-auth/ACqZMry9XetqtHeCwbcsWj7nXCXxzkIBks5tMRI-gaJpZM4RCyLU .

yordis commented 6 years ago

@willsoto could you elaborate on what was the workaround so we could understand what you did and learn about it? Do reverse engineering.

I am curious of what you call workaround because it means we need fix something.

willsoto commented 6 years ago

Originally I was trying to use session based or cookie based auth, but no matter what I tried it didn't seem to work. Even if the cookie was issued (it could have been the default Phoenix cookie, I don't know) Guardian couldn't seem to pick it up.

FWIW, the only issue here might be a lack of documentation. I am new to Phoenix and Elixir (but have used many other frameworks and languages) and it just felt like I had a knowledge gap when I was reading the docs. Even when I followed the readme to the letter, I couldn't get it to work.

The workaround was to switch to header based auth and just put the token on there.

It is honestly probably the case that my expectations around what session based auth or cookie based were supposed to do is wrong, and so I felt the behavior I was seeing was "broken" when it's just my understanding of it that is wrong.

As far as I could tell, my code looked exactly like so many examples I found on the web and this issue tracker, but still didn't work.

I appreciate the follow up but I'm so far past it at this point (and I'm honestly fine with the way it works) that I really don't mind if this issue gets closed.

On Fri, Jan 19, 2018, 5:17 PM Yordis Prieto notifications@github.com wrote:

@willsoto https://github.com/willsoto could you elaborate on what was the workaround so we could understand what you did and learn about it? Do reverse engineering.

I am curious of what you call workaround because it means we need fix something.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ueberauth/guardian/issues/434#issuecomment-359105075, or mute the thread https://github.com/notifications/unsubscribe-auth/ACqZMuvl9MORRnrxhFeT_iKox1Rq5-Wbks5tMRSVgaJpZM4RCyLU .

yordis commented 6 years ago

Folks,

feel free to reopen it if you are having this issue.

hisapy commented 6 years ago

Hello ladies and gentlemen.

I'm having this same issue after upgrading from 0.14 to 1.0.1 but it was my fault.

I have a GraphQL API built with Absinthe and to get a JWT I query a login mutation. In the upgrade I just copied the pipeline implementation and updated my router. Basically the error was caused because in the new version you have to explicitly allow blank resource.

# We need to allow blank is needed to accept a login mutation request to get the token. 
# Future requests with a valid token will load the resource correctly.
plug(Guardian.Plug.LoadResource, allow_blank: true)

# In the old version I was calling this plug without `ensure: true`

In might be worth to add this caveat in the upgrading guides

yordis commented 6 years ago

@hisapy yes please, make a PR with some documentation updates

hisapy commented 6 years ago

I'll do it ASAP, probably tomorrow

jdppettit commented 5 years ago

Sorry to necro this, but I seem to be having a similar issue here and I can't seem to figure out what exactly I am doing wrong.

config.exs

config :foo, Foo.Guardian,
  issue: "foo",
  secret_key: "supersekrit"

Foo.Guardian

defmodule Foo.Guardian do
  use Guardian, otp_app: :foo

  def subject_for_token(resource, _claims) do
    { :ok, "foo"}
    {:ok, to_string(resource.id)}
  end

  def resource_from_claims(claims) do
    IO.inspect claims
    user = %{}
    IO.puts "foo"
    { :error, :foobar_error }
    case user do
      nil ->
        { :error }
      _ ->
      { :ok, %{id: user.id }}
    end
  end
end

^ random junk added to confirm whether or not this is running at all

pipeline

  pipeline :authorized do
    plug :fetch_session
    plug Guardian.Plug.Pipeline, module: Foo.Guardian,
      error_handler: Foo.AuthErrorHandler
    plug Guardian.Plug.VerifySession
    plug Guardian.Plug.LoadResource
  end

Adding allow_blank: true to the LoadResource call does work, without it I am getting the same error the OP mentioned as I am using a temporary auth error handler from the tutorial.

Any help would be super appreciated here.