Airbnb clone, create a session token

Join the 2022 Full-Stack Web Dev Bootcamp!


This post is part of a new series where we build a clone of Airbnb with Next.js. See the first post here.

We worked on registration previously, introducing a POST call to the /api/auth/register URL in the file pages/api/auth/register.js.

Right now when we receive this POST request, we invoke User.create() to add a new user to the database.

First, I now want to check if the user exists before calling User.create. We use User.findOne() to do so. If the user does not exist we create it:

let user = await User.findOne({ where: { email } })

if (!user) {
  user = await User.create({ email, password })
  res.end(JSON.stringify({ status: 'success', message: 'User added' }))
} else {
  res.end(JSON.stringify({ status: 'error', message: 'User already exists' }))
}

Let’s do one more thing: we want to create a session token.

The session is a random string stored in the session_token field.

I first write this function to create a random string of a specific length:

const randomString = (length) => {
  const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let result = ''
  for (let i = length; i > 0; --i) {
    result += chars[Math.floor(Math.random() * chars.length)]
  }
  return result
}

Then I call this to get a token:

const sessionToken = randomString(255)

And I call User.update() to update the user’s data stored in the table, passing this token and a session expiration date set 30 days from now:

const sessionToken = randomString(255)
const d = new Date()
d.setDate(d.getDate() + 30)
User.update(
  {
    session_token: sessionToken,
    session_expiration: d
  },
  { where: { email } }
)

Here is the full code so far:

import { User, sequelize } from '../../../model.js'

const randomString = (length) => {
  const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let result = ''
  for (let i = length; i > 0; --i) {
    result += chars[Math.floor(Math.random() * chars.length)]
  }
  return result
}

export default async (req, res) => {
  if (req.method !== 'POST') {
    res.status(405).end() //Method Not Allowed
    return
  }

  const { email, password, passwordconfirmation } = req.body

  if (password !== passwordconfirmation) {
    res.end(
      JSON.stringify({ status: 'error', message: 'Passwords do not match' })
    )
    return
  }

  let user = await User.findOne({ where: { email } })

  if (!user) {
    user = await User.create({ email, password })

    const sessionToken = randomString(255)
    const d = new Date()
    d.setDate(d.getDate() + 30)
    User.update(
      {
        session_token: sessionToken,
        session_expiration: d
      },
      { where: { email } }
    )
    res.end(JSON.stringify({ status: 'success', message: 'User added' }))
  } else {
    res.end(JSON.stringify({ status: 'error', message: 'User already exists' }))
  }
}

See the code on GitHub

Next part: Implement login

Want to become a better Web Developer? Join the 2022 Web Development Bootcamp!

⭐️⭐️⭐️ Join the 2022 Web Development Bootcamp ⭐️⭐️⭐️