DEV Community

Cover image for Password Protection for Cloudflare Pages

Password Protection for Cloudflare Pages

Maxi Ferreira on January 12, 2022

Cloudflare Pages is a fantastic service for hosting static sites: it is extremely easy to set-up, it deploys your sites automatically on every comm...
Collapse
 
juliankoehn profile image
Julian

Thanks @charca, saved a bunch of time <3

Collapse
 
spaut profile image
Ron Pritchard

Hey Maxi, thanks for writing this tool and publishing it. It's a lifesaver.

Quick question: is there a way to preserve the navigation after auth? It looks like the script always redirects to the root. I'm wondering if I can go directly to something like domain.com/some-page after authenticating.

Thanks,
Ron

Collapse
 
charca profile image
Maxi Ferreira

Hey @spaut, sorry for the delay. I'm glad you've found the script useful!

Yes, that's definitely possible. I've updated the example repo with that behavior, so it now redirects to the page you were trying to access after login. You can see the diff where this feature was implemented here.

Collapse
 
gusdn22 profile image
Deviosa

Hey Maxi, this is so useful. Thanks for sharing and explanation. May I just ask because I noticed that URLs that ends with an extension such as PDF aren't working. The PDF file did not open after authenticating but instead just stayed on the authentication page.

Collapse
 
kennyray profile image
Ken

When I try this with Next.js 14 w/ Typscript I'm getting an error with template.ts that I've gone round and round with. Seems like no matter what syntactical change I make, it breaks something else. I changed to arrow function and then the HTML comes out as a string rather than HTML so doesn't render. I'm sure this is a simple adjustment, but it is elluding me.

Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
⨯ Error: Unsupported Server Component type: Module
at stringify ()
at stringify ()

Collapse
 
wbtk profile image
Black White

maybe
//cfp_login
const hashedCfpPassword = await sha256(env.CFP_PASSWORD || '');
const redirectPath = (redirect && redirect.toString()) || '/';

//utils
import { CFP_COOKIE_KEY } from './constants';

export async function sha256(str: string | undefined): Promise {
if (str === undefined) {
return '';
}

const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(str));
return Array.prototype.map
.call(new Uint8Array(buf), (x) => ('00' + x.toString(16)).slice(-2))
.join('');
}

export async function getCookieKeyValue(password?: string): Promise {
const hash = await sha256(password);
return ${CFP_COOKIE_KEY}=${hash};
}

Collapse
 
kidino profile image
Iszuddin Ismail

I just got started with Cloudflare Pages. Do you think it is possible to extend this with D1 to store users table and their passwords?

Collapse
 
phong profile image
Nguyễn Hữu Phong

Thank you so much for this post. I'm not actually a developer but I can understand almost everything of your explaination.

Collapse
 
closingtags profile image
Dylan Hildenbrand

Great post! I assumed this was possible but glad to see that I won't have to reinvent the wheel when attempting to implement it myself.

Collapse
 
tigr profile image
Tigran Sargsyan

The demo says "Incorrect password, please try again." when I try to use the password "test".

Collapse
 
charca profile image
Maxi Ferreira

Thanks for calling that out! I've fix it and updated the article. The password is password.

Collapse
 
mariocarabotta profile image
mariocarabotta

Hi Maxi, thank you for sharing this, I might implement it for my website.
Is there an easy way to password-protect individual pages?

Thank you!