redpoll

redpoll

Hi, today I generated a new auth admin in my phoenix 1.7.7 app

mix phx.gen.auth Accounts Admin admins

and after creating a new admin using the built-in form everything seems to be alright. Well.. almost everything. When logged in, the admin token is seen

session: %{
  "_csrf_token" => "qWmAvVGzs...",
  "admin_return_to" => "/dashboard",
  "admin_token" => <<195, 253, (...)>>,
  "live_socket_id" => "admins_sessions:w_3CYZGonln4 ..."
}

and following a page, for example admins/log_in successfully redirect to /. The problem is that the routes which require authenticated admin still require it. I am clicking on the settings button which goes to /admins/settings and the toast says me I need to log in, but i was already logged in. I tried to put different route in that scope, but the error still remains with the “new” live route.

  scope "/", TennisWeb do
    pipe_through([:browser, :require_authenticated_admin])

    live_session :require_authenticated_admin,
      on_mount: [{TennisWeb.AdminAuth, :ensure_authenticated}] do
      live("/admins/settings", AdminSettingsLive, :edit)
      live("/admins/settings/confirm_email/:token", AdminSettingsLive, :confirm_email)
    end
  end

I have no idea what could be wrong. For sure the wrong is with me, but what could it be?
Best Regards

Showing Posts 1 to 10

smathy

smathy

You see that session even in the logs for /admin/settings?

redpoll

redpoll OP

I get this

session: %{
  "_csrf_token" => "qWmAvVGzs6FdwNf",
  "admin_return_to" => "/admins/settings",
  "admin_token" => <<195, 253, 194, >>,
  "live_socket_id" => "admins_sessions:w_3CYZGonln4PjFEsFoxjF=",
  "phoenix_flash" => %{"error" => "You must log in to access this page."}
}

smathy

smathy

Ok cool, so then can you see the SQL in your logs where it’s trying to select from admins_tokens? And then I’d double check the record itself in the DB with something like (assuming you only have a couple of token entries):

Tennis.Repo.all Tennis.Accounts.AdminToken

Is there any reason that query isn’t pulling up that token record? (it can only be the token, context or inserted_at)

redpoll

redpoll OP

[info] GET /admins/settings
[debug] Processing with TennisWeb.AdminSettingsLive.edit/2
  Parameters: %{}
  Pipelines: [:browser, :require_authenticated_admin]
[info] Sent 302 in 2ms
[debug] Phoenix.Router halted in :require_authenticated_admin/2
[info] GET /admins/log_in
[debug] Processing with TennisWeb.AdminLoginLive.new/2
  Parameters: %{}
  Pipelines: [:browser, :redirect_if_admin_is_authenticated]
[debug] QUERY OK source="admins_tokens" db=0.4ms idle=1810.1ms
SELECT a1."id", a1."email", a1."hashed_password", a1."confirmed_at", a1."inserted_at", a1."updated_at" FROM "admins_tokens" AS a0 INNER JOIN "admins" AS a1 ON a1."id" = a0."admin_id" WHERE ((a0."token" = $1) AND (a0."context" = $2)) AND (a0."inserted_at" > $3::timestamp + (-(60)::numeric * interval '1 day')) [<<91, 7, 196, 251, 187, 59, 123, 226, 144, 242, 237, 59, 30, 141, 172, 17, 182, 223, 9, 196, 98, 3, 145, 43, 120, 187, 24, 4, 60, 174, 153, 132>>, "session", ~U[2023-08-15 07:21:17.743217Z]]
↳ Phoenix.LiveView.Utils.assign_new/3, at: lib/phoenix_live_view/utils.ex:79
[info] Sent 302 in 2ms
[info] GET /

As I read this, it first stops to require_authenticated_admin, it thinks that there is no admin logged in, it redirects to admins/log_in, but oh, there is an admin.

[
  %Tennis.Accounts.AdminToken{
    __meta__: #Ecto.Schema.Metadata<:loaded, "admins_tokens">,
    id: 1,
    token: <<114, 195, 157, 169, 173, 83, 53, 117, 118, 11, 231, 83, 96, 36, 15,
      147, 51, 95, 25, 250, 239, 158, 80, 40, 63, 82, 98, 76, 60, 209, 214,
      65>>,
    context: "confirm",
    sent_to: "email@email.com",
    admin_id: 1,
    admin: #Ecto.Association.NotLoaded<association :admin is not loaded>,
    inserted_at: ~N[2023-08-14 13:52:24]
  },
  %Tennis.Accounts.AdminToken{
    __meta__: #Ecto.Schema.Metadata<:loaded, "admins_tokens">,
    id: 3,
    token: <<89, 211, 31, 60, 6, 252, 8, 27, 0, 27, 37, 212, 226, 216, 144, 185,
      169, 42, 128, 206, 205, 179, 101, 156, 98, 117, 162, 251, 41, 208, 180,
      27>>,
    context: "session",
    sent_to: nil,
    admin_id: 1,
    admin: #Ecto.Association.NotLoaded<association :admin is not loaded>,
    inserted_at: ~N[2023-08-14 14:09:25]
  },
  %Tennis.Accounts.AdminToken{
    __meta__: #Ecto.Schema.Metadata<:loaded, "admins_tokens">,
    id: 4,
    token: <<195, 253, 194, 97, 145, 168, 158, 89, 248, 62, 49, 68, 176, 90, 49,
      140, 94, 213, 129, 77, 83, 14, 34, 128, 46, 158, 194, 117, 218, 217, 130,
      7>>,
    context: "session",
    sent_to: nil,
    admin_id: 1,
    admin: #Ecto.Association.NotLoaded<association :admin is not loaded>,
    inserted_at: ~N[2023-08-14 16:50:56]
  },
  %Tennis.Accounts.AdminToken{
    __meta__: #Ecto.Schema.Metadata<:loaded, "admins_tokens">,
    id: 6,
    token: <<96, 18, 203, 223, 86, 21, 223, 199, 81, 181, 7, 82, 249, 87, 236,
      227, 29, 249, 41, 72, 96, 244, 167, 170, 121, 125, 45, 13, 249, 166, 240,
      42>>,
    context: "session",
    sent_to: nil,
    admin_id: 1,
    admin: #Ecto.Association.NotLoaded<association :admin is not loaded>,
    inserted_at: ~N[2023-08-15 07:25:30]
  }
]

The query is pulling up token records. But, if the token in the [debug] ends with 153, 132 - there is no suck token in Tennis.Accounts.AdminToken. That means the token is not properly recorded to SQL (postgres)?

smathy

smathy

Yeah, so your first request there for GET /admins/settings has no session, so no surprise you halted at require_auth... and were redirected to login. I’d like to see after that login what happens if you THEN requested /admins/settings again.

redpoll

redpoll OP

[info] POST /admins/log_in
[debug] Processing with TennisWeb.AdminSessionController.create/2
  Parameters: %{"_csrf_token" => "ESw_VzEnZ1lfGBZqMQcRYz1aHCUtGx0ODonfWjP3krARTTwQwnzvoqgc", "admin" => %{"email" => "email@email", "password" => "[FILTERED]", "remember_me" => "false"}}
  Pipelines: [:browser, :redirect_if_admin_is_authenticated]
[debug] QUERY OK source="admins" db=1.0ms queue=0.6ms idle=1621.0ms
SELECT a0."id", a0."email", a0."hashed_password", a0."confirmed_at", a0."inserted_at", a0."updated_at" FROM "admins" AS a0 WHERE (a0."email" = $1) ["ykostov@pm.me"]
↳ Tennis.Accounts.get_admin_by_email_and_password/2, at: lib/tennis/accounts.ex:43
[debug] QUERY OK db=2.0ms queue=1.5ms idle=1814.0ms
INSERT INTO "admins_tokens" ("admin_id","context","token","inserted_at") VALUES ($1,$2,$3,$4) RETURNING "id" [1, "session", <<114, 209, 156, 4, 227, 124, 191, 227, 219, 137, 126, 16, 172, 31, 131, 208, 139, 87, 121, 35, 192, 226, 101, 146, 222, 75, 87, 90, 123, 245, 88, 14>>, ~N[2023-08-15 13:33:13]]
↳ Tennis.Accounts.generate_admin_session_token/1, at: lib/tennis/accounts.ex:225
[info] Sent 302 in 202ms
[info] GET /
[debug] Processing with TennisWeb.PageLive.Index.show/2
  Parameters: %{}
  Pipelines: [:browser]
session: %{
  "admin_token" => <<114, 209, 156, 4, 227, 124, 191, 227, 219, 137, 126, 16,
    172, 31, 131, 208, 139, 87, 121, 35, 192, 226, 101, 146, 222, 75, 87, 90,
    123, 245, 88, 14>>,
  "live_socket_id" => "admins_sessions:ctGcBON8v-PbiX4QrB-D0ItXeSPA4mWS3ktXWnv1WA4=",
  "phoenix_flash" => %{"info" => "Welcome back!"}
}
[debug] QUERY OK source="admins_tokens" db=0.8ms queue=1.6ms idle=1865.0ms
SELECT a1."id", a1."email", a1."hashed_password", a1."confirmed_at", a1."inserted_at", a1."updated_at" FROM "admins_tokens" AS a0 INNER JOIN "admins" AS a1 ON a1."id" = a0."admin_id" WHERE ((a0."token" = $1) AND (a0."context" = $2)) AND (a0."inserted_at" > $3::timestamp + (-(60)::numeric * interval '1 day')) [<<114, 209, 156, 4, 227, 124, 191, 227, 219, 137, 126, 16, 172, 31, 131, 208, 139, 87, 121, 35, 192, 226, 101, 146, 222, 75, 87, 90, 123, 245, 88, 14>>, "session", ~U[2023-08-15 13:33:13.872013Z]]
↳ TennisWeb.PageLive.Index.mount/3, at: lib/tennis_web/live/page_live/index.ex:14

it seems ok to me. And this is after log in and requestiong /admin/settings

[info] GET /admins/settings
[debug] Processing with TennisWeb.AdminSettingsLive.edit/2
  Parameters: %{}
  Pipelines: [:browser, :require_authenticated_admin]
[info] Sent 302 in 2ms
[debug] Phoenix.Router halted in :require_authenticated_admin/2
[info] GET /admins/log_in
[debug] Processing with TennisWeb.AdminLoginLive.new/2
  Parameters: %{}
  Pipelines: [:browser, :redirect_if_admin_is_authenticated]
[debug] QUERY OK source="admins_tokens" db=1.6ms idle=1758.1ms
SELECT a1."id", a1."email", a1."hashed_password", a1."confirmed_at", a1."inserted_at", a1."updated_at" FROM "admins_tokens" AS a0 INNER JOIN "admins" AS a1 ON a1."id" = a0."admin_id" WHERE ((a0."token" = $1) AND (a0."context" = $2)) AND (a0."inserted_at" > $3::timestamp + (-(60)::numeric * interval '1 day')) [<<114, 209, 156, 4, 227, 124, 191, 227, 219, 137, 126, 16, 172, 31, 131, 208, 139, 87, 121, 35, 192, 226, 101, 146, 222, 75, 87, 90, 123, 245, 88, 14>>, "session", ~U[2023-08-15 13:35:10.838007Z]]
↳ Phoenix.LiveView.Utils.assign_new/3, at: lib/phoenix_live_view/utils.ex:79
[info] Sent 302 in 4ms
[info] GET /
[debug] Processing with TennisWeb.PageLive.Index.show/2
  Parameters: %{}
  Pipelines: [:browser]
session: %{
  "_csrf_token" => "PK5U2B2Tway5URNSI4RIY90b",
  "admin_return_to" => "/admins/settings",
  "admin_token" => <<114, 209, 156, 4, 227, 124, 191, 227, 219, 137, 126, 16,
    172, 31, 131, 208, 139, 87, 121, 35, 192, 226, 101, 146, 222, 75, 87, 90,
    123, 245, 88, 14>>,
  "live_socket_id" => "admins_sessions:ctGcBON8v-PbiX4QrB-D0ItXeSPA4mWS3ktXWnv1WA4=",
  "phoenix_flash" => %{"error" => "You must log in to access this page."}
}

From what I understand and read - it works expected until that pipeline [:browser, :require_authenticated_admin]

smathy

smathy

Hmm, and after that if you go to / you’re still logged in?

redpoll

redpoll OP

yes. Could there be something wrong with my Live mount for @current_admin?

def mount(_params, session, socket) do
    current_admin_token = session["admin_token"]
    IO.inspect(session, label: "session")

    if is_nil(current_admin_token) do
      {:ok, socket |> assign(:current_admin, nil)}
    else
      current_admin = Accounts.get_admin_by_session_token(current_admin_token)
      {:ok, socket |> assign(:current_admin, current_admin)}
    end
  end
smathy

smathy

Ummm, where did that code come from? :face_with_peeking_eye:

redpoll

redpoll OP

well, after generating auth, there was @current_admin not found error, so I built this myself in / live view. When there is not admin token → nil, else pass the current_admin. I did this last year in a phx 1.6 and it was fine.

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews