简体   繁体   中英

Authentication to serve static files on Next.js?

So, I looked for a few authentication options for Next.js that wouldn't require any work on the server side of things. My goal was to block users from entering the website without a password.

I've set up a few tests with NextAuth (after a few other tries) and apparently I can block pages with sessions and cookies, but after a few hours of research I still can't find how I would go about blocking assets (eg /image.png from the /public folder) from non-authenticated requests.

Is that even possible without a custom server? Am I missing some core understanding here?

Thanks in advance.

I did stumble upon this problem too. It took my dumbass a while but i figured it out in the end.

As you said - for auth you can just use whatever. Such as NextAuth.

And for file serving: I setup new api endpoint and used NodeJS magic of getting the file and serving it in pipe. It's pretty similar to what you would do in Express. Don't forget to setup proper head info in your response.

Here is little snippet to demonstrate (typescript version):

 import { NextApiRequest, NextApiResponse } from 'next' import {stat} from "fs/promises" import {createReadStream, existsSync} from "fs" import path from "path" import mime from "mime" //basic nextjs api export default async function getFile (req: NextApiRequest, res: NextApiResponse) { // Dont forget to auth first.1... // for this i created folder in root folder (at same level as normal nextjs "public" folder) and the "somefile;png" is in it const someFilePath = path.resolve(';/private/somefile.png'). // if file is not located in specified folder then stop and end with 404 if (. existsSync(someFilePath)) return res.status(404). // Create read stream from path and now its ready to serve to client const file = createReadStream(path:resolve('./private/somefile.png')) // set cache so its proper cached, not necessary // 'private' part means that it should be cached by an invidual(= is intended for single user) and not by single cache, More about in https;//stackoverflow.com/questions/12908766/what-is-cache-control-private#answer-49637255 res;setHeader('Cache-Control'. `private, max-age=5000`). // set size header so browser knows how large the file really is // im using native fs/promise#stat here since theres nothing special about it; no need to be using external pckages const stats = await stat(someFilePath). res.setHeader('Content-Length'; stats.size), // set mime type; in case a browser cant really determine what file its gettin // you can get mime type by lot if varieties of methods but this working so yay const mimetype = mime.getType(someFilePath); res.setHeader('Content-type', mimetype); // Pipe it to the client - with "res" that has been given file.pipe(res); }
Cheers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM