nextjs route middleware for authentication

bry*_*yan 11 javascript reactjs next.js

I'm trying to figure out an appropriate way of doing authentication, which I know is a touchy subject on the GitHub issue page.

My authentication is simple. I store a JWT token in the session. I send it to a different server for approval. If I get back true, we keep going, if I get back false, it clears the session and puts sends them to the main page.

In my server.js file I have the following (note- I am using the example from nextjs learn and just adding isAuthenticated):

function isAuthenticated(req, res, next) {
  //checks go here

  //if (req.user.authenticated)
   // return next();

  // IF A USER ISN'T LOGGED IN, THEN REDIRECT THEM SOMEWHERE
  res.redirect('/');
}

server.get('/p/:id', isAuthenticated, (req, res) => {
  const actualPage = '/post'
  const queryParams = { id: req.params.id }
  app.render(req, res, actualPage, queryParams)
})
Run Code Online (Sandbox Code Playgroud)

This works as designed. If I refresh the page /p/123, it will redirect to the /. However, if I go there via a next/link href, it doesn't. Which I believe is because it's not using express at this point but next's custom routing.

Is there a way I can bake in a check for every single next/link that doesn't go through express so that I can make sure the user is logged in?

bry*_*yan 16

下次聊天的Tim帮我解决了这个问题。可以在这里找到解决方案但我会引用他,以便大家看到:

我还创建了一个示例骨架模板,您可以看一下。


Nat*_*ugh 13

编辑:更新了 Next 12.2+ 的答案

注意:以下内容是从官方博客文章复制的,因为 SO 通常不鼓励随着时间的推移而变得陈旧/失效的链接 https://nextjs.org/blog/next-12-2#middleware-stable

中间件现已稳定在 12.2 中,并根据用户反馈改进了 API。

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

// If the incoming request has the "beta" cookie
// then we'll rewrite the request to /beta
export function middleware(req: NextRequest) {
  const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
  req.nextUrl.pathname = isInBeta ? '/beta' : '/';
  return NextResponse.rewrite(req.nextUrl);
}

// Supports both a single value or an array of matches
export const config = {
  matcher: '/',
};
Run Code Online (Sandbox Code Playgroud)

迁移指南

https://nextjs.org/docs/messages/middleware-upgrade-guide 重大更改

  • 无嵌套中间件
  • 无响应体
  • Cookie API 已改进
  • 新的用户代理助手
  • 不再有页面匹配数据
  • 对内部 Next.js 请求执行中间件

如何升级

您应该在应用程序中声明一个中间件文件,该文件应位于pages目录旁边,并且命名时不带前缀_。您的中间件文件仍然可以具有.ts.js扩展名。

将为应用程序中的每个路由调用中间件,并且可以使用自定义匹配器来定义匹配过滤器。/about/*以下是触发和的中间件示例/dashboard/:path*,自定义匹配器在导出的配置对象中定义:

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  return NextResponse.rewrite(new URL('/about-2', request.url))
}

// Supports both a single string value or an array of matchers
export const config = {
  matcher: ['/about/:path*', '/dashboard/:path*'],
}
Run Code Online (Sandbox Code Playgroud)

编辑:下一个 > 12 和 < 12.2 的过时答案

随着 Next.js 12 的发布,现在对使用 Vercel Edge Functions 的中间件提供了测试版支持。

https://nextjs.org/blog/next-12#introducing-middleware

中间件使用严格的运行时,支持 fetch 等标准 Web API。> 这可以使用 next start 开箱即用,也可以在使用 Edge Functions 的 Vercel 等 Edge 平台上使用。

要在Next.js中使用中间件,您可以创建文件pages/_middleware.js。在此示例中,我们使用标准 Web API 响应 (MDN):

// middleware.ts
import { NextRequest, NextResponse } from 'next/server';

// If the incoming request has the "beta" cookie
// then we'll rewrite the request to /beta
export function middleware(req: NextRequest) {
  const isInBeta = JSON.parse(req.cookies.get('beta') || 'false');
  req.nextUrl.pathname = isInBeta ? '/beta' : '/';
  return NextResponse.rewrite(req.nextUrl);
}

// Supports both a single value or an array of matches
export const config = {
  matcher: '/',
};
Run Code Online (Sandbox Code Playgroud)

JWT 身份验证示例

next.config.js

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  return NextResponse.rewrite(new URL('/about-2', request.url))
}

// Supports both a single string value or an array of matchers
export const config = {
  matcher: ['/about/:path*', '/dashboard/:path*'],
}
Run Code Online (Sandbox Code Playgroud)

pages/_middleware.js

// pages/_middleware.js

export function middleware(req, ev) {
  return new Response('Hello, world!')
}
Run Code Online (Sandbox Code Playgroud)

pages/api/_middleware.js

const withTM = require('@vercel/edge-functions-ui/transpile')()

module.exports = withTM()
Run Code Online (Sandbox Code Playgroud)

pages/api/index.js

import { NextRequest, NextResponse } from 'next/server'
import { setUserCookie } from '@lib/auth'

export function middleware(req: NextRequest) {
  // Add the user token to the response
  return setUserCookie(req, NextResponse.next())
}
Run Code Online (Sandbox Code Playgroud)


gdf*_*dfg 3

中没有middlewareAPI 路由NextJS,但有 HOC,您可以使用它们连接到数据库 - 选择用户等: https: //hoangvvo.com/blog/nextjs-middleware