Last time we set up a basic installation of Pow. Today we’ll add on session persistence, registration confirmation and password reset functionality.
So let’s get at it!
Getting started
If you’ve been following along you can continue with the code from part 1, or you can grab the code from GitHub.
Clone the Repo:
If cloning:
Terminal
Let’s create a branch for today’s work:
Terminal
And make sure we have our dependencies and database set-up.
Terminal
Terminal
Note: before running ecto.setup
you may need to update the username / password database settings in dev.config
to match your local postgres settings, i.e.
/config/dev.config …line 69
Terminal
With that out of the way… let’s see where we are starting from.
Terminal
If we navigate to http://localhost:4000/ we’ll see our application.
If we create a user and login, we’ll see we have access to our products page and the navigation links update intelligently based on the fact that a user is logged in.
One thing you’ll notice is if we close and re-open our browser we lose our user session (i.e. we get logged out).
This isn’t always the behaviour we’d prefer, so let’s see how we can add session persistence.
Adding session persistence
Pow
provides us with an easy way of including session persistence, the first step is to update config.exs
.
/config/config.exs …line 20
We’ve added the PowPersistentSession
extension as well as a controller_callback
.
Next we need to update endpoint.ex
, adding a new Plug
for session persistence.
/lib/warehouse_web/endpoint.ex …line 45
Finally we should update the login form to give the user the option of whether they want their session to be persisted or not. We’ll add a simple check-box.
/lib/warehouse_web/templates/pow/session/new.html.eex …line 18
To see this all in action we need to restart the server.
Terminal
Now we have the option of persistenting sessions:
If we select the Remember me
option we’ll find we don’t need to log in again after closing and re-opening our browser. Session persistence… done! Was that easy or what!
Next let’s see how we can add registration confirmation and password resets.
Adding registration confirmation and password resets
We’ll handle registration confirmation and password resets in one go as the set-up steps are fairly similar for both.
We need a migration for the email confirmation functionality so let’s start by creating that.
Terminal
We’ll then run the migration.
Terminal
Next we need to update config.exs
with the new extensions.
/config/config.exs …line 20
Now we need to update user.ex
, including the extensions and adding a changeset
.
/lib/warehouse/users/user.ex
Finally we also need to add some routes.
/lib/warehouse_web/router.ex
We’ve added a new use
statement (use Pow.Extension.Phoenix.Router, otp_app: :warehouse
) and then updated the first scope
section to include pow_extension_routes
.
Before testing things out, let’s add a reset password link in our sign in form.
/lib/warehouse_web/templates/pow/session/new.html.eex …line 26
Now if we start up our server we should be good to go.
Terminal
We see our new Reset password
link in the sign in form.
And if we click it we get:
Doh… so what has happened here? Well if you recall we are using customized versions of the Pow
templates, i.e. we generated the templates and added web_module: WarehouseWeb
to config.exs
. This means that our newly added functionality also expects generated versus default templates. So we need to generate the templates.
Terminal
And with that, we should be good.
But wait, we have one more step left, if we submit the reset password form as things currently stand we’ll get.
As per the Pow
README
we also need to set-up mailer support. This is easy to do, the instructions in the README
provide instructions for setting up a mock that will output our email contents to the console log. This works perfect for the purposes of development.
First we create the mailer.
Terminal
/lib/warehouse_web/pow/mailer.ex
And then we need to update the Pow
configuration in config.exs
.
/config/config.exs …line 20
After a server restart everything is good.
Terminal
Hitting submit yields the following:
And in our console we see:
Following the link in the console we get.
Sweet!
If we register a new user, we’ll see the registration confirmation functionality is now up and working as well.
Following the link in the console gives us:
So that does it for adding registration confirmation and password resets!
Let’s have a quick look at a few other customizations before finishing off for today.
Other customizations
One thing I’ve noticed is when signing out of the application the user is taken to the sign in page. I’d prefer if the user was redirected to the root of the application. We can use Callback routes to change this behaviour.
Callback routes
The list of available callback routes can be seen in the source code at: https://github.com/danschultzer/pow/blob/master/lib/pow/phoenix/routes.ex.
https://github.com/danschultzer/pow/blob/master/lib/pow/phoenix/routes.ex
We’re going to want to make use of the after_sign_out_path
callback. We can do so by creating a pow.routes
file.
Terminal
And adding the following contents.
/lib/warehouse_web/pow/routes.ex
All we’re doing above is indicating we want to go to the index
of the page_controller
on sign out.
We need another entry in config.exs
as well, specifying the routes_backend
configuration.
/config/config.exs …line 20
Now if we restart the server and logout we’ll be redirected to the main page of our application instead of the sign in page.
Fantastic!
Customizing or adding flash messages
Another area of Pow
that we can customize is the flash messages shown to the user. For instance, currently if the user is not signed in and tries to access a page that is protected, they are redirected to the sign in page and no flash message appears. We’ll add a message for this scenario.
The first step is to create a new module for our messages.
Terminal
And then add a message for user_not_authenticated
.
/lib/warehouse_web/pow/messages.ex
The hex documentation provides a good reference for the messages available within Pow
:
The source code is also a good reference and is located at: https://github.com/danschultzer/pow/blob/master/lib/pow/phoenix/messages.ex.
For the reset_password
and email_confirmation
extensions the code is at: https://github.com/danschultzer/pow/blob/master/lib/extensions/reset_password/phoenix/messages.ex.
https://github.com/danschultzer/pow/blob/master/lib/extensions/reset_password/phoenix/messages.ex
https://github.com/danschultzer/pow/blob/master/lib/extensions/email_confirmation/phoenix/messages.ex
Like the other Pow
customizations we need to update config.exs
. We need to add a messages_backend
entry.
/config/config.exs …line 20
Now with a server restart, when trying to access the ‘Products’ pages without signing in, we see the message we added:
Sweet!
Summary
So that’s it for our tour of Pow
. I’d recommend you check out the README
and the source code to gain a further understanding of how things work.
I’m really impressed with the way Pow
is structured and how easy it is to use, set-up and customize. Hopefully you’ll find Pow
useful for your projects as well!
Thanks for reading and I hope you enjoyed the post!