【问题标题】:nextjs route middleware for authenticationnextjs 路由中间件进行身份验证
【发布时间】:2018-12-27 19:18:13
【问题描述】:

我正在尝试找出一种适当的身份验证方式,我知道这是GitHub issue page 上的一个敏感主题。

我的身份验证很简单。我在会话中存储了一个 JWT 令牌。我将其发送到另一台服务器以供批准。如果我返回 true,我们继续,如果我返回 false,它会清除会话并将它们发送到主页。

在我的 server.js 文件中,我有以下内容(注意 - 我使用的是来自 nextjs learn 的示例,只是添加了 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)
})

这按设计工作。如果我刷新页面/p/123,它将重定向到/。但是,如果我通过next/link href 去那里,它不会。我认为这是因为此时它没有使用 express,而是使用 next 的自定义路由。

有没有一种方法可以为每个未通过 express 的next/link 进行检查,以便确保用户已登录?

【问题讨论】:

    标签: javascript reactjs next.js


    【解决方案1】:

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

    我还创建了一个example skeleton template,你可以看看。

    --

    2021 年 7 月编辑 - 警告:这是一个过时的解决方案,尚未确认可与最新版本的 next.js 一起使用。使用骨架模板需要您自担风险。

    【讨论】:

    • 所有链接都已失效 :(
    【解决方案2】:

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

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

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

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

    // pages/_middleware.js
    
    export function middleware(req, ev) {
      return new Response('Hello, world!')
    }
    

    JWT 认证示例

    next.config.js:

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

    pages/_middleware.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())
    }
    

    pages/api/_middleware.js:

    import type { NextRequest } from 'next/server'
    import { nanoid } from 'nanoid'
    import { verifyAuth } from '@lib/auth'
    import { jsonResponse } from '@lib/utils'
    
    export async function middleware(req: NextRequest) {
      const url = req.nextUrl
    
      if (url.searchParams.has('edge')) {
        const resOrPayload = await verifyAuth(req)
    
        return resOrPayload instanceof Response
          ? resOrPayload
          : jsonResponse(200, { nanoid: nanoid(), jwtID: resOrPayload.jti })
      }
    }
    

    pages/api/index.js:

    import type { NextApiRequest, NextApiResponse } from 'next'
    import { verify, JwtPayload } from 'jsonwebtoken'
    import { nanoid } from 'nanoid'
    import { USER_TOKEN, JWT_SECRET_KEY } from '@lib/constants'
    
    export default async function handler(
      req: NextApiRequest,
      res: NextApiResponse
    ) {
      if (req.method !== 'GET') {
        return res.status(405).json({
          error: { message: 'Method not allowed' },
        })
      }
      try {
        const token = req.cookies[USER_TOKEN]
        const payload = verify(token, JWT_SECRET_KEY) as JwtPayload
        res.status(200).json({ nanoid: nanoid(), jwtID: payload.jti })
      } catch (err) {
        res.status(401).json({ error: { message: 'Your token has expired.' } })
      }
    }
    

    【讨论】:

      【解决方案3】:

      middleware 中没有 API 路由,NextJS 中没有 middleware,但是有 HOC,您可以使用它来连接到 db - 选择用户等: https://hoangvvo.com/blog/nextjs-middleware

      【讨论】:

        猜你喜欢
        • 2022-12-03
        • 2018-07-25
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 2021-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多