When I visit http://localhost:4004/auth/sign_in The result is correct
{
"data": {
"id": 1,
"token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIiLCJleHAiOjE2Njc0NjAzODcsImlhdCI6MTY2NzQ1ODU4NywiaXNzIjoiIiwianRpIjoiYjQ1Yzc2NWUtNTJkYS00MTIxLWEyNGUtN2VjNGYwODFhZDZmIiwibmJmIjoxNjY3NDU4NTg2LCJzdWIiOiIxIiwidHlwIjoiYWNjZXNzIn0.jPlcZjVo784A6_nPyZ8fJatO343TDxsvv-YFp9_Gs5dTSH3DjOqg12lQ24ciRi-JElG36__8I9ybBNazv7nnbA",
"user_name": "gaofeng"
}
}
And then I took the token to visit http://localhost:4004/user , the token is set in the header, and the result is incorrect
Header is
Result is
{
"message": "invalid_token"
}
This is the new content in my code
In config.exs.
config :ueberauth, Ueberauth,
base_path: "/auth/sign_in",
providers: [
identity: {Ueberauth.Strategy.Identity, [
callback_methods: ["POST", "GET"],
nickname_field: :username,
param_nesting: "user",
uid_field: :username
]}
]
config :store_api, StoreApiWeb.Guardian,
issure: "XXX",
secret_key: "secret_key"
config :store_api, StoreApiWeb.Plug.AuthAccessPipeline,
module: StoreApi.Auth,
error_handler: StoreApiWeb.Plug.AuthErrorHandler
In auth module(auth.ex)
defmodule StoreApi.Auth do
use Guardian, otp_app: :store_api
def subject_for_token(%{id: id}, _claims) do
{:ok, to_string(id)}
end
def subject_for_token(_, _) do
IO.inspect "subject_for_token"
{:error, :reason_for_error}
end
def resource_from_claims(%{"sub" => id}) 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.
resource = StoreApi.Accounts.get_user!(id)
IO.inspect "resource_from_claims"
IO.inspect resource
{:ok, resource}
end
def resource_from_claims(_claims) do
IO.inspect "resource_from_claims=====_claims"
{:error, :no_claims_sub}
end
end
Auth Controller(authentication_controller.ex)
defmodule StoreApiWeb.AuthenticationController do
use StoreApiWeb, :controller
alias StoreApi.Accounts
alias StoreApi.Accounts.User
plug Ueberauth
def identity_callback(conn, %{"user" => user_params}) do
IO.inspect(user_params)
user_name = user_params["user_name"]
password = user_params["password"]
handle_user_conn(Accounts.check_user(user_name, password), conn)
end
defp handle_user_conn(user, conn) do
# IO.inspect(user)
case user do
{:ok, user} ->
{:ok, jwt, _full_claims} =
StoreApi.Auth.encode_and_sign(user, %{}, secret: "custom", ttl: {30, :minute})
conn
|> put_resp_header("authorization", "Bearer " <> jwt)
|> json(%{data: %{token: jwt, user_name: user.user_name, id: user.id}})
# Handle our own error to keep it generic
{:error, msg} ->
conn
|> put_status(401)
|> json(%{data: %{ status: false, msg: msg}})
end
end
end
In pulg
(auth_access_pipeline.ex)
defmodule StoreApiWeb.Plug.AuthAccessPipeline do
use Guardian.Plug.Pipeline, otp_app: :store_api
plug Guardian.Plug.VerifySession, claims: %{"typ" => "access"}
plug Guardian.Plug.VerifyHeader, realm: "Bearer", claims: %{"typ" => "access"}
plug Guardian.Plug.EnsureAuthenticated
plug Guardian.Plug.LoadResource, ensure: true
end
auth_error_handler.ex
defmodule StoreApiWeb.Plug.AuthErrorHandler do
import Plug.Conn
import Phoenix.Controller, only: [json: 2]
def auth_error(conn, {type, _reason}, _opts) do
conn
|> put_status(401)
|> json(%{message: to_string(type)})
|> halt()
end
end
In my routers
defmodule StoreApiWeb.Router do
use StoreApiWeb, :router
pipeline :api do
plug :accepts, ["json"]
end
scope "/api", StoreApiWeb do
pipe_through :api
resources "/user", UserController, except: [:new, :edit]
end
pipeline :browser do
plug(:accepts, ["json"])
end
pipeline :authenticated do
plug StoreApiWeb.Plug.AuthAccessPipeline
end
# 用户登录
scope "/auth", StoreApiWeb do
pipe_through :browser
post "/sign_in", AuthenticationController, :identity_callback
end
@doc """
用户信息相关API
"""
scope "/user", StoreApiWeb do
pipe_through :browser
pipe_through :authenticated
# 获取所有用户信息
resources "/", UserController, except: [:new, :edit]
post "/detail", UserController, :show
#post "/delete", UserController, :delete
end
@doc """
应用信息相关API
"""
scope "/appinfo", StoreApiWeb do
pipe_through :browser
# 获取应用信息信息
resources "/", AppinfoController, except: [:new, :edit]
# 新增应用
#post "/user_create", UserController, :user_create
end
# Enables LiveDashboard only for development
#
# If you want to use the LiveDashboard in production, you should put
# it behind authentication and allow only admins to access it.
# If your application does not have an admins-only section yet,
# you can use Plug.BasicAuth to set up some basic authentication
# as long as you are also using SSL (which you should anyway).
if Mix.env() in [:dev, :test] do
import Phoenix.LiveDashboard.Router
scope "/" do
pipe_through [:fetch_session, :protect_from_forgery]
live_dashboard "/dashboard", metrics: StoreApiWeb.Telemetry
end
end
# Enables the Swoosh mailbox preview in development.
#
# Note that preview only shows emails that were sent by the same
# node running the Phoenix server.
if Mix.env() == :dev do
scope "/dev" do
pipe_through [:fetch_session, :protect_from_forgery]
forward "/mailbox", Plug.Swoosh.MailboxPreview
end
end
end
Thanks indeed!!!