setting up google OAuth in phoenix ▶▶▶

  • Its been almost a week or so learning the phoenix framework and elixir. I’ve gotten a bit of understanding on how the framework uses the MVC architecture to make building web applications easier, and how elixir’s functional programming capabilities make functional programing great again 😜
  • This post will focus on how to set up Google OAuth as a third-party login option for user authentication into the app built with the phoenix web framework.
    [ Assumption is that one already has a decent understanding of how both the language(elixir) and framework(phoenix) work.]
  • For every phoenix project created, a mix.exs file is generated. Inside this file is a function deps. This function contains all the dependencies that come already installed in the phoenix framework.

Step 1️⃣ Add Ueberauth and Google Dependencies

  • Also, inside the same mix.exs file is another function, application that executes everytime the phoenix app starts. We have add the two dependencies as well.
  • The application function now looks like this, below

Step 2️⃣ Run command to install the dependencies

$ mix deps.get

which should show the entire list of dependencies including the ones we just added.

Step 3️⃣ Update config.exs file

Step 4️⃣ Create a google client ID

  • Add those two values to the config.exs file as below
updated config file with ueberauth, client_id and client_secret
  • Once the above configuration steps are all done, now we can add code that shows how to create new controller that handles authentication, and also appropriate routes for signing in and out of the application.

Next Steps

Step 5️⃣ Add routes for signing in.

  • line 6. specifies a GET request with;
    /:provider will be a google, or any other 3rd party login option.
    AuthController is name of controller we will create.
    :request is a pre-defined function.
  • line 7. specifies a GET request with;
    /:provider/callback for redirecting from the google api with user profile.
    :callback is a function that we will implement.

Step 6️⃣ Create user model and add database migrations.

  • Add user.ex as a model in the models folder. Code below defines a User module with schema that specifies the type of each field in the database.
  • Run this command that adds a migration file to your project.
$ mix ecto.gen.migrations add_users
  • This generates a migration file under the /priv/repo/migrationsfolder. this file an empty function change(). Add the following code to that empty function that creates a table with its columns specified as in the schema.
  • Finally run this command to create the actual table in the postgres database.
$ mix ecto.migrate

Step 7️⃣ Create Controller for handling Authentication.

  • line 2: we use pattern matching to extract the auth object from the conn parameter.
  • line 3: still using pattern matching to extract the user_params from the auth object. The user_params include the user_token, email, and provider.
  • line 4: creates changeset object that now contains the the values we need.
  • line 6: we then pass that changeset object to the signin function.
  • The signin() checks to see if that user exists in the database, if not it inserts the new user into the database, or else it just logs them back into the app.

Step 8️⃣ Create plug that checks user session:

  • In our case, we will create a module plug, since it will be used in different sections of our code where we would prefer to know if a user is logged in.
    Create a new folder plugs inside of the controller directory. then create a file inside the plugs folder. our module plug is user.ex defined below. (check # comments in code for each line explanation)
a module plug must contain two functions: ie init() and call()
  • Now, inside the router.ex file, add this module plug to the list of pipeline plugs that get executed wherever a request is sent from a user. as seen below on line 10 (line 10 contains plug we just created)

Step 9️⃣ Add sign-in button on layout_view page.

  • line 4: checks the conn object that contains the user details, and checks if it exits, and if so, it displays the option for the to signout.
  • line 10: is for when the user is not logged(meaning the @conn.assigns[:user] returns nil), then show them the sign in button.

Step 🔟 Add functionality for signing out

  • Just add this sign_out function to the auth_controller
  • line 5: sets the drop key to true, thereby closing the session for user
  • line 6: then redirects user to the index function of the controller with developer_path

🙌 END 🙌

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store