Phoenix Ueberauth can't log back in, get 'no case clause matching: nil'

I am working on a Phoenix app using Ueberauth. I set up the authorization process, using GitHub, which worked. The problem is now that I logged out, I can’t log back in. The error appears when I click on a ‘Sign In’ button, which calls the Ueberauth :request function. This worked fine at first. Since then, I added a channel and am trying to create and send a user token to the server as verification, so the user can create or edit topics. I had that working while I was logged in, but, I logged out and now can’t sign back in. There is a record for me as a user in the database, and GitHub has verified the app.
The error is in the Ueberauth code. Line 97 is highlighted:

[lib/ueberauth/strategy/github/oauth.ex](http://localhost:4000/auth/github)

94   defp check_credential(config, key) do
95     check_config_key_exists(config, key)
96
97     case Keyword.get(config, key) do
98       value when is_binary(value) ->
99         config
100
101       {:system, env_key} ->
102          case System.get_env(env_key) do

I think the problem is that conn.assigns.user is being set to nil when I log out (not sure of this, though).
This is what I see in the terminal:

[info] GET /auth/github
[debug] Processing with DiscussWeb.AuthController.request/2
  Parameters: %{"provider" => "github"}
  Pipelines: [:browser]
[info] Sent 500 in 18ms
[error] #PID<0.1190.0> running DiscussWeb.Endpoint (connection #PID<0.1178.0>, stream id 4) terminated
Server: localhost:4000 (http)
Request: GET /auth/github
** (exit) an exception was raised:
    ** (CaseClauseError) no case clause matching: nil
etc.

This is the :browser pipeline:

pipeline :browser do
    plug Ueberauth
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, {DiscussWeb.LayoutView, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
    plug Discuss.Plugs.SetUser
    plug :put_user_token
  end

This is the SetUser plug call function:

def call(conn, _opts) do
user_id = get_session(conn, :user_id)

    cond do
        user = user_id && Repo.get(User, user_id) ->
            assign(conn, :user, user)> 
        true ->> 
            assign(conn, :user, nil)
    end
end

The ‘Log Out’ button runs a function the drops the session, so user_id get set to nil in the SetUser plug. Is this where my problem is, and how do I fix this? I can’t proceed if I can’t log in.

You can have two pipelines - :browser and :secured. For pages which don’t require authentication - you can use browser. For pages which require authentication, you can use both - [:browser, :secured]

pipeline :browser do
    plug Ueberauth
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_live_flash
    plug :put_root_layout, {DiscussWeb.LayoutView, :root}
    plug :protect_from_forgery
    plug :put_secure_browser_headers
end

pipeline :secured do
    plug Discuss.Plugs.SetUser
end


scope "/", YourWebApp do
  pipe_through :browser

  get "/login", LoginController, :index
  post "/login", LoginController, :index
end

scope "/", YourWebApp do
  pipe_through [:browser, :secured]

  get "/", PageController, :index
end
1 Like

Interesting approach. I will try this soon.
Thanks.

1 Like

https://hexdocs.pm/phoenix/routing.html#creating-new-pipelines

Guessing by the fact that you are using System.get_env(env_key) you have a .env file set up. So go ahead and run

source .env in your root directory terminal before running your application.