📝

JWT Authentication【25(終) Secure】

2022/10/27に公開約4,000字

JWT Authentication【25(終) Secure】

YouTube: https://youtu.be/xMVlCqaUHNM

https://youtu.be/xMVlCqaUHNM

前回までで認証機能の実装は完了しているのですが、
ログインした際にコンソールにsameSiteの警告がでていますので、
今回はこちらが表示されないようにしようと思います!

こちらはexpressで作成しているバックエンドの
loginメソッドのjwtをcookieで設定している部分の
secureとsameSiteの部分を変更します。

src/authControllers.tsx
    if (token) {
      res.setHeader('Set-Cookie', cookie.serialize('jwt', token, {
        httpOnly: true,
        // secure: req.app.get('env') !== 'development'
        secure: true,
        sameSite: "none"
      }))
    }

secureをtrueにするとポストマンでjwtのcookieを扱えなくなりますので
ご注意ください。

全文はこちら

src/authControllers.tsx
import {Request, Response} from 'express'
import { prisma } from '../utils/prismaClient'
import bcrypt from 'bcrypt'
import jwt from 'jsonwebtoken'
import { jwtSecretKey } from '../utils/jwtSecretKey'
import cookie from 'cookie'

export const register = async (req: Request, res: Response) => {
  const { email, name, password, confirm_password } = req.body

  if (password !== confirm_password ) {
    res.status(400).json({
      'message': "Password do not match confirm password."
    })
    return
  }

  const hashedPassword = await bcrypt.hash(password, 10)

  try {
    const user = await prisma.user.create({
      data: {
        email: email,
        name: name,
        password: hashedPassword
      },
      select: {
        id: true,
        email: true,
        name: true,
      }
    })
    res.status(200).json(user)
  } catch (error) {
    res.status(500).json({"error": error})
  }
}

export const login = async (req: Request, res: Response) => {
  const { email, password } = req.body

  try {
    const user = await prisma.user.findUnique({
      where: {
        email: email
      },
      select: {
        id: true,
        name: true,
        email: true,
        password: true
      }
    })

    if (user === null) {
      return res.status(404).json({error: "user do not exist"})
    }

    const compared = await bcrypt.compare(password, user.password)

    if (!compared) {
      return res.status(400).json({error: "password wrong"})
    }

    const token = jwt.sign({userId: user.id}, jwtSecretKey, {algorithm: 'HS256'})

    if (token) {
      res.setHeader('Set-Cookie', cookie.serialize('jwt', token, {
        httpOnly: true,
        // secure: req.app.get('env') !== 'development'
        secure: true,
        sameSite: "none"
      }))
    }

    const resUser = {
      id: user.id,
      name: user.name,
      email: user.email
    }

    res.status(200).json(resUser)

  } catch (error: any) {
    res.status(500).json({error: error})
  }
}

export const logout = (req: Request, res: Response) => {

  try {
    res.setHeader('Set-Cookie', cookie.serialize('jwt', '', {
      httpOnly: true,
      secure: req.app.get('env') !== 'development',
      maxAge: Number(new Date(0)),
      // secure: true,
      // sameSite: "none"
    }))

    res.status(200).json({message: 'logout success'})
  } catch (error: any) {
    res.status(500).json({error: error})
  }
}

export const getUserByJwt = async (req: Request, res: Response) => {
  const { userId } = req.user
  try {
    const user = await prisma.user.findUnique({
      where: {
        id: userId,
      },
      select: {
        id: true,
        email: true,
        name: true,
      }
    })
    if (user === null) {
      res.setHeader('Set-Cookie', cookie.serialize('jwt', '', {
        httpOnly: true,
        secure: req.app.get('env') !== 'development',
        maxAge: Number(new Date(0)),
        // secure: true,
        // sameSite: "none"
      }))
      res.status(404).json({"message": "User do not exist"})
      return
    }
    res.status(200).json(user)
  } catch (error) {
    res.setHeader('Set-Cookie', cookie.serialize('jwt', '', {
      httpOnly: true,
      secure: req.app.get('env') !== 'development',
      maxAge: Number(new Date(0)),
      // secure: true,
      // sameSite: "none"
    }))
    res.status(500).json({"error": error})
  }
}

Discussion

ログインするとコメントできます