Generate the Authentication Layer
Explore how to use the phx.gen.auth generator to build a well-structured authentication layer in Phoenix. Learn to add dependencies, run the generator, execute database migrations, and verify functionality with tests. Understand how this plug-based approach integrates with LiveView for managing logged-in users.
We'll cover the following...
In the following lessons, we’ll learn how to use the generator to build an authentication layer, we’ll see how the pieces of generated code fit together to handle the responsibilities of authentication, and we’ll even see how LiveView uses the authentication service to identify and operate on the logged-in user.
What is phx.gen.auth?
To build a well-structured authentication layer for Phoenix requests, we can use the phx.gen.auth application generator. This generator is rapidly becoming the authentication standard for all Phoenix applications. Though phx.gen.auth is not a LiveView framework, all LiveViews begin as standard web requests. That means a plug-based approach suits our purposes just fine to authenticate our users in LiveView, as well as throughout the rest of our application. Using this generator, we’ll be able to generate, rather than hand-roll, a solution that’s mostly complete, and adapt it to meet any further requirements we might have.
We’ll start by installing and running the generator.
Adding the dependency
To use this authentication generator, we need to add phx_gen_auth to our application’s dependency list. To do so, we navigat to the pento/mix.exs and added the phx_gen_auth library like this:
Notice we’re using version 0.4. If you’d like, you can use a later version instead. Most of the approaches will still work, though we might have to tweak some of the code here or there.
The next step is to fetch all of the code for our dependencies, and the code their mix projects depend on, into our local project. We fetched the dependencies with the mix deps.get command.
Our dependency isn’t authentication code itself. It’s the code that will generate the authentication layers. We’ll need to run that generator to get a working authentication layer.
Let’s let the generator fly.
Running the generator
Before we generate our code, we’ll take advantage of a common pattern for many mix tasks: running them without arguments will give us guidance about any options we need. Run the following command without any arguments in the terminal below to trigger a small bit of help, like this:
And the output looks something like this:
Don’t worry about the vocabulary. We’ll cover contexts, schemas, and the like in more detail later. For now, know that running this generator creates a module called a context and another module called a schema. Look at a context as an API for a service, and a schema as a data structure describing a database table.
This generator is giving us the command to build an authentication layer. It would generate a context called Accounts and a schema called User with a plural of users. The generator’s defaults seem reasonable. Go to the terminal and run the command given below:
How to run migrations
Elixir separates the concepts of working with database records from that of working with the database structure. Our generator gave us the “database structure” code in the form of a set of Ecto migrations for creating database tables. Ecto is the framework for dealing with databases within Elixir, and migrations are the part of Ecto that create and modify database entities. Before our application can work with a database table, our migrations will need to be run to ensure that the database table exists, has the right structure for the data we’ll put in it, and has the right set of indexes for performance.
Fortunately, along with the rest of the authentication code, phx.gen.auth built some migrations for us. We need to only run them. Head over to the terminal and execute the migrate command shown here:
Perfect. We made sure the case insensitive extension exists, and we created the tables for users and tokens. Along the way, we created a few indexes for performance as well. Before we dive in too deeply, let’s make sure the overall service is working, end to end. Tests would be a great way to do so.
Testing the service
To make sure everything works, run the tests in terminal below like this:
And, we will see something like this:
If everything works fine, we’re ready to work on the code.