Skip to content

Instantly share code, notes, and snippets.

@mtt87
Created December 21, 2021 14:39
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mtt87/cb9f36665165112468b92aa9fb470c7e to your computer and use it in GitHub Desktop.
Save mtt87/cb9f36665165112468b92aa9fb470c7e to your computer and use it in GitHub Desktop.
Add password protection to any Vercel website, save $150/month.
import { addYears } from 'date-fns'
import { NextRequest, NextResponse } from 'next/server'
function middleware(req: NextRequest) {
if (req.nextUrl.pathname.startsWith('/api')) {
return NextResponse.next()
}
if (process.env.VERCEL_ENV !== 'preview') {
return NextResponse.next()
}
if (req.cookies['let-me-in'] === process.env.BASIC_AUTH_PASSWORD) {
return NextResponse.next()
}
const basicAuth = req.headers.get('authorization')
if (basicAuth) {
const auth = basicAuth.split(' ')[1]
const [user, pwd] = Buffer.from(auth, 'base64').toString().split(':')
if (user === 'username' && pwd === process.env.BASIC_AUTH_PASSWORD) {
const response = NextResponse.next()
const expire = addYears(new Date(), 1).toUTCString()
response.headers.set(
'Set-Cookie',
`let-me-in=${process.env.BASIC_AUTH_PASSWORD}; Domain=.example.com; Secure; HttpOnly; Expires='${expire}'`,
)
return response
}
}
return new Response('Auth required', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="Secure Area"',
},
})
}
export default middleware
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment