— NodeJS One-Time Password Auth
source on github
One-Time (Single Use) Password Authentication Strategy using a JSON Web Token (JWT) and Cookies.
- JSON Web Tokens (JWTs)
- Sequelize (Mysql or Postgres)
- Nodemailer (Using a SMTP Server)
What is this?
This boilerplate code is a web app auth strategy that generates a one-time-use password that is emailed to a user. Upon login, the password is discarded and all further auth is done with a JSON Web Token (JWT) stored in a cookie on the client.
Cookies must be enabled by the users browser for this auth scheme to work. The only thing stored in the cookie is a JWT.
JWT’s can be used forever to login, or until it is expired. There is no simple way to log out when using a JWT for auth, as they are stateless and stored on the client. One method of “logging out” the user is to clear cookies. You may want to set cookie Max-Age, Domain, and other settings to your preference.
Notion.so uses a similar login-flow that this code is unabashadly inspired by.
Summary of login flow
- User visits web app and submits their email via login form at
- DB inserts new row using the UNIQUE email in a USER Table. Otherwise, select the user if the email exists.
- Server generates a password and updates the PASSWORD column of the user row
- Server adds a JWT to the clients cookie using the user ID and the password as payload
- Server sends the user an email with the password
- User enters the password at
- Assuming the user didn’t clear their cookies since requesting a password, the server uses the password and ID from the JWT to authenticates the user against the password they submitted
- DB deletes one-time password from USER row
- If authenticated, a new JWT is created with the user ID, and is replaced in the cookie.
- User is now authenticated. The JWT from the cookie is used to auth future requests.
- To log out, server clears the clients cookie.
Endpoints in this demo
GET /public root
POST /registerPost form w/email field
POST /loginPost form w/password field
GET /loginThe default redirect if not authenticated
POST /logoutClear cookies to “log out”
GET /protectedA demo of protected route that resolves if user is authenticated
Suggestions and TODO
- Config cookie Max-Age, Domain, and etc based on your needs
.envand edit your settings
- If you have nodemon installed,
npm run start, otherwise
node email-test.js to test sending mail w/your mailserver.