2017-12-17 12 views
0

로그인 및 사용자 작성 경로를 제외한 모든 경로를 보호하려는 Phoenix 앱이 있습니다. 이를 위해 Guardian 및 ComeOnIn 패키지를 사용합니다. (나는 this 블로그를 따라 갔다.)
나는 세션 루트에서 클라이언트에게 토큰을 보낼 수 있었고, 사용자 생성도 잘되었다.
그러나 모든 사용자 (예 : 사용자 모듈의 색인 경로)를 표시하려고 할 때 인증 오류가 발생합니다. (내 테스트에서 아직 GUI가 없습니다)
여기에 제가 한 것입니다 : 사용자 컨트롤러 :인증 인증

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 
: 여기

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 

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 

그리고 여기가 가디언에 필요한 모듈 인 router.ex입니다

오류 처리기 :

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 

그리고 마지막으로 내 테스트 파일에서

:

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 

매번는 내가 항상 내 오류 처리기에서 오는 인증이 이미 전송 오류를 얻을 내 테스트를 실행합니다.
테스트를 통과하기 위해 누락 된 사항은 무엇입니까?

EDIT

: 여기
출력이다

1) 시험 인덱스리스트의 모든 사용자 (WarehouseWeb.UserControllerTest) 시험/warehouse_web/제어기/user_controller_test.exs 32
** (플러그. Conn.AlreadySentError) 이미 전송 된 응답
코드 : CONN = GET CONN, user_path (CONN : 인덱스)
스택 트레이스 :
(플러그) lib 디렉토리/플러그/conn.ex : 508 : Plug.Conn.resp/3
,451,515,(플러그) LIB/플러그/conn.ex : 495 : Plug.Conn.send_resp/3
(보호자) LIB/보호자/플러그/ensure_authenticated.ex : 61 : Guardian.Plug.EnsureAuthenticated.respond/1
(창고) LIB/warehouse_web/인증/auth_pipeline.ex : 1 : WarehouseWeb.Guardian.AuthPipeline.plug_builder_call/2
(웨어) LIB/warehouse_web/router.ex : 8 : WarehouseWeb.Router.api_auth/2
(웨어) lib/warehouse_web/router.ex : 1 : WarehouseWeb.Router의 익명 fn/1. match_route/4
(phoenix) lib/phoenix/router.ex : 273 : Phoenix.Router. /1
(웨어) LIB/warehouse_web/endpoint.ex : 1 : WarehouseWeb.Endpoint.plug_builder_call/2
(웨어) LIB/warehouse_web/endpoint.ex : 1 : WarehouseWeb.Endpoint.call/2
(피닉스) lib 디렉토리/피닉스/테스트/conn_test.ex : 224 : Phoenix.ConnTest.dispatch/5
테스트/warehouse_web/컨트롤러/user_controller_test.exs : 33 : (테스트)

+0

stacktrace에 전체 오류 메시지를 게시 할 수 있습니까? – Dogbert

답변

1

모든 코드가 보인다 꽤 광산과 비슷합니다.유일한 차이점은 테스트 인증입니다 ... 거기에 여분의 세미콜론이 있습니다.

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

대신 할 수

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

희망이어야한다. 문제가 지속될 경우 알려주십시오