2017-12-17 5 views
0

Ich habe eine Phoenix-App, wo ich alle Routen mit Ausnahme der Login-und Benutzererstellungsroute sichern möchte. Um dies zu erreichen, verwende ich die Guardian- und ComeOnIn-Pakete. (Ich habe versucht, this Blog zu folgen)
Ich geschafft, ein Token an den Client in der Sitzungsroute zu senden, und die Erstellung eines Benutzers funktioniert auch.
Aber, wenn ich alle Benutzer anzeigen möchte (dh die Indexroute des Benutzermoduls), erhalte ich einen Authentifizierungsfehler (in meinen Tests habe ich noch nicht die GUI)
Hier ist, was ich getan habe: Benutzer Controller:Failling Authentifizierung

defmodule WarehouseWeb.UserController do 
    use WarehouseWeb, :controller 

    alias Warehouse.Account 
    alias Warehouse.Account.User 

    action_fallback WarehouseWeb.FallbackController 

    def index(conn, _params) do 
    users = Account.list_users() 
    render(conn, "index.json-api", data: users) 
    end 
# ... ... 
end 

hier ist die router.ex

defmodule WarehouseWeb.Router do 
    use WarehouseWeb, :router 

    pipeline :api do 
    plug :accepts, ["json", "json-api"] 
    end 

    pipeline :api_auth do 
    plug WarehouseWeb.Guardian.AuthPipeline 
    end 

    scope "/api", WarehouseWeb do 
    pipe_through :api 
    post "/register", RegistrationController, :create 
    post "/token", SessionController, :create, as: :login 
    end 

    scope "/api", WarehouseWeb do 
    pipe_through :api_auth 

    resources "/users", UserController, except: [:new, :edit] 
    end 
end 

Und hier sind die notwendigen Module für Guardian:

defmodule WarehouseWeb.Guardian.AuthPipeline do 
    use Guardian.Plug.Pipeline, otp_app:  :warehouse, 
           module:  WarehouseWeb.Guardian, 
           error_handler: WarehouseWeb.Guardian.AuthErrorHandler 

    plug Guardian.Plug.VerifyHeader 
    plug Guardian.Plug.EnsureAuthenticated 
end 

defmodule Warehouse.Guardian do 
    use Guardian, otp: :warehouse, 
       secret_key: "some secret" 

    def subject_for_token(resource, _claims) do 
    {:ok, to_string(resource.id)} 
    end 
    def resource_from_claims(claims) do 
    user = Warehouse.Account.get_user!(claims["sub"]) 
    {:ok, user} 
    end 
end 

Die Fehlerbehandlung:

defmodule WarehouseWeb.Guardian.AuthErrorHandler do 
    import Plug.Conn 

    def auth_error(conn, {type, reason}, opts) do 
    IO.inspect "authentication is not working!!" 
    body = Poison.encode!(%{message: to_string(type)}) 
    send_resp(conn, 401, body) 
    end 
end 

Und endlich meine Testdatei:

defmodule WarehouseWeb.UserControllerTest do 
    use WarehouseWeb.ConnCase 

    alias Warehouse.Account 
    alias Warehouse.Account.User 

    @create_attrs %{email: "some email", firstname: "some firstname", lastname: "some lastname", password: "some password"} 
    @update_attrs %{email: "some updated email", firstname: "some updated firstname", lastname: "some updated lastname", password: "some updated password"} 
    @invalid_attrs %{email: nil, firstname: nil, lastname: nil, password: nil} 

    def fixture(:user) do 
    {:ok, user} = Account.create_user(@create_attrs) 
    user 
    end 

    setup %{conn: conn} do 
    # create user to be logged in 
    {:ok, user} = Account.create_user(%{email: "[email protected]", real_password: "abc123", real_password_confirmation: "abc123"}) 

    # create token for session 
    {:ok, jwt, _claims} = Account.authenticate(%{user: user, password: "abc123"}) 

    # add authorization header to the request 
    conn = conn 
    |> put_req_header("authorization", "Bearer: #{jwt}") 
    |> put_req_header("accept", "application/json") 

    {:ok, %{conn: conn, user: user}} 
    end 

    describe "index" do 
    test "lists all users", %{conn: conn} do 
     conn = get conn, user_path(conn, :index) 
     assert json_response(conn, 200)["data"] == [] 
    end 
    end 
end 

Jedesmal, wenn ich meinen Test laufen bekomme ich immer die Fehler Authentifizierung bereits senden, die von meinem Fehler-Handler kommt.
Was fehlt mir, um meinen Test bestehen zu lassen?

EDIT:
Hier ist die Ausgabe:

1) Test Index listet alle Benutzer (WarehouseWeb.UserControllerTest) Test/warehouse_web/controllers/user_controller_test.exs: 32
** (Plug. Conn.AlreadySentError) die Antwort bereits
Code gesendet: conn = get anschl, user_path (conn,: index)
Stacktrace:
(Stecker) lib/Stecker/conn.ex: 508: Plug.Conn.resp/3
(Stecker) lib/Stecker/conn.ex: 495: Plug.Conn.send_resp/3
(Guardian) lib/Wächter/Stecker/ensure_authenticated.ex: 61: Guardian.Plug.EnsureAuthenticated.respond/1
(WarehouseWeb.Guardian.AuthPipeline.plug_builder_call/2
(Lager) lib/warehouse_web/router.ex: 8: WarehouseWeb.Router.api_auth/2
(Lager) lib/warehouse_web/router.ex: 1: anonymous fn/1 in WarehouseWeb.Router. match_route/4
(Phönix) lib/phoenix/router.ex: 273: Phoenix.Router. Anruf/1
(Lager) lib/warehouse_web/endpoint.ex: 1: WarehouseWeb.Endpoint.plug_builder_call/2
(Lager) lib/warehouse_web/endpoint.ex: 1: WarehouseWeb.Endpoint.call/2
(phoenix) lib/phoenix/test/conn_test.ex: 224: Phoenix.ConnTest.dispatch/5
Test/warehouse_web/controllers/user_controller_test.exs: 33: (Test)

+0

Können Sie die vollständige Fehlermeldung mit dem Stacktrace buchen? – Dogbert

Antwort

1

Alle Code scheint ziemlich ähnlich wie bei mir, wo es funktioniert.Der einzige Unterschied ist Ihre Testauthentifizierung ... Sie haben dort ein zusätzliches Semikolon.

put_req_header("authorization", "Bearer #{token}") 

Statt

put_req_header("authorization", "Bearer: #{token}") 

Hoffnung

Es sollte

sein, das hilft. Lassen Sie mich wissen, wenn das Problem weiterhin besteht

Verwandte Themen