Dlacreme

Dlacreme

Hi,

I have some experience with Phoenix Liveview but I never had this kind of issue so I hope you can help. I just created a brand new application and I am implementing a Oauth2 auth using ueberauth_facebook

The oauth2 flow is working well, but when I try to return the newly authenticated user and the related JWT, the render function crashes. The log shows that render received a full Plug.Conn%{} struct a second parameter, which doesn’t make any sense.

My routes are setup for JSON (pipe_through :api)

  scope "/auth", PlxWeb do
    pipe_through :api

    get "/:provider/callback", AuthController, :callback
    post "/:provider/callback", AuthController, :callback
    # ...
  end

My controller/handler is quite simple:

  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
    IO.puts("Callback success")

    case Auth.authenticate_from_callback(auth) do
      {:ok, %{token: _t, user: _u} = auth_info} ->
        IO.puts("user authenticated > #{inspect(auth_info)}")
        conn
        |> put_status(:ok)
        |> render("200.json", %{auth_info})

      {:error, reason} ->
        IO.puts("failed to authenticated user")
        conn
        |> put_status(:internal_server_error)
        |> render("500.json", reason)
    end
  end

And my view and smaller:

  def render("200.json", %{token: _t, user: _u} = payload) do
    IO.puts("Payload > #{inspect(payload)}")
    %{message: "ok", payload: payload}
  end

This code prints the following logs:

> "Callback success"
# means the provider authentication was ok
> "user authenticated > %{token: 'expected token', user: %User{id: xxx, name: 'im a normal user'}}"
# so far all good
> "Payload >  %{conn: %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{layout: false, ueberauth_auth: %Ueberauth.Auth{credentials: (+20 lines)"
# why did my token/user map transformed to this?
-> crash: "`protocol Jason.Encoder not implemented for %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{kind: :error, layout: false` (+20 lines)"
# which makes sense since the Plug.Conn struct is not expected to be encoded

I don’t have a stacktrace of what’s happening. I’ve been stuck for a couple of hours, I’ve tried difference thing. I don’t even understand how the pattern matching in the view doesn’t fail

Thanks for your kind help, it’s probably some stupid mistakes

Showing Posts 1 to 7

mbuhot

mbuhot

This line looks suspect:

|> render("200.json", %{auth_info})

I’d usually expect something like:

|> render("200.json", auth_info: auth_info)

Then in your view:

def render("200.json", %{auth_info: %{token: _t, user: _u} = payload}) do

It’s expected that the conn is added to the assigns between the call to render in your controller and then Phoenix calling your views render function. Take a read of Phoenix.Controller.render to see how it works.

Dlacreme

Dlacreme OP

thanks for your reply @mbuhot

I’ve tried different formats and they all have the same results(the one you suggested included, I just tested) - like you suggested I ll take a look at the implementation of render, that might help to understand what’s going on. Thanks !

cenotaph

cenotaph

You have something in your assigns that plug conn cannot convert to html.

Ie you have some sort of embedded struct or module implementation or a method.

Your suth_nfo might be correct object but this line makes things worse.

Just do token: token and test it out.

cenotaph

cenotaph

Well there it is. io.inspect is not the same as render output method. How should render know how to convert Userstruct into html?

I am not sure where you got that piece of code,. It is not readable and open to massive exploits for security reasons.

Dlacreme

Dlacreme OP

Thanks all for your reply.

@cenotaph the |> render("200.json", %{auth_info}) line is just one of many things I’ve tried to make it work. Once I got something that work I can clean the code. Also User correctly implement Jason.Encode:

defimpl Jason.Encoder, for: Plx.Auth.User do
  def encode(value, opts) do
    Jason.Encode.map(Map.take(value, [:id, :name, :description]), opts)
  end
end

Anyway, finally I changed some code for something even more basic and did that:

# Controller
      {:ok, _} ->
        conn
        |> put_status(:ok)
        |> render("200.json", %{hello: "world"})

# View
  def render("200.json", info) do
    IO.puts("info > #{inspect(info)}")
    %{data: info}
  end

And it still fails with the same error:

protocol Jason.Encoder not implemented for %Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{kind: :error, layout: false, reason: 

I will just create a brand new app and try again. I must have made an error in the configs

amnu3387

amnu3387

I think the problem is you’re treating render as you would the helper json that indeed takes a map or any json encodable element as the last and renders it as json.

In this case I think you will have to do it as a regular assign, such as render(conn, "vie.json", auth_info: auth_info) and then pick %{auth_info: auth_info} from the parameters on the json render.

Dlacreme

Dlacreme OP

I got it, I simply forgot import Phoenix.Controller at the top of my controller… sorry and thanks to all for your help.

— All posts loaded —

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
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews