【问题标题】:next.js & next-auth When I send http request in getServerSideProps, getSession returns null in secured API Routenext.js & next-auth 当我在 getServerSideProps 中发送 http 请求时,getSession 在安全 API 路由中返回 null
【发布时间】:2022-10-20 19:57:54
【问题描述】:

我正在尝试保护 API 路由,并且在不同页面的客户端和服务器端调用此 API 路由。

test 页面上,它返回401 error

test2 页面上,它很好地返回了内容。

我猜当我在getServerSideProps 中发送http 请求时它不会通过session

我的问题是,如何保护客户端和服务器端使用的 API 路由?

/pages/test

import React from 'react';
import axios from 'axios';
import { getSession } from 'next-auth/react';

const Test = (props) => {
    return <div>test</div>;
};
export const getServerSideProps = async (context) => {
    // it returns session data
    const session = await getSession(context);

    // it returns error
    const res = await axios.get('/api/secret');
    return {
        props: {
            session,
            secret: res.data,
        },
    };
};
export default Test;

/pages/test2

import React, { useEffect } from 'react';
import axios from 'axios';
import { useSession, getSession } from 'next-auth/react';

const Test = (props) => {
    const { data: session } = useSession();

    useEffect(() => {
        const fetchData = async () => {
            const res = await axios.get('/api/secret');
            console.log(res.data);
        };
        fetchData();
    }, [session]);

    return <div>test</div>;
};

export default Test;

/pages/api/secret

import { getSession } from 'next-auth/react';

const handler = (req, res) => {
    const { method } = req;
    switch (method) {
        case 'GET':
            return getSomething(req, res);
        default:
            return res.status(405).json('Method not allowed');
    }
};
const getSomething = async (req, res) => {
    const session = await getSession({ req });
    console.log(session);
    if (session) {
        res.send({
            content: 'Welcome to the secret page',
        });
    } else {
        res.status(401).send({
            err: 'You need to be signed in.',
        });
    }
};

export default handler;

【问题讨论】:

  • 我不知道这是否是您的具体问题,但您的 API 路由处理程序需要是 async
  • @Ben 感谢您告诉我!

标签: javascript next.js next-auth


【解决方案1】:

我找到了解决方案。

export const getServerSideProps = async (ctx) => {
    const session = await getSession(ctx);
    const headers = ctx.req.headers;
    if (session) {
        const data = (
            await axios.get(`${process.env.NEXTAUTH_URL}/api/secret`, {
                headers: { Cookie: headers.cookie },
            })
        
        return {
            props: {
                data,
            },
        };
    } else {
        return {
            redirect: {
                destination: '/login',
                permanent: false,
            },
        };
    }
};

/pages/api/secret

import { getSession } from 'next-auth/react';

const handler = async (req, res) => {
    const { method } = req;
    switch (method) {
        case 'GET':
            return await getSomething(req, res);
        default:
            return res.status(405).json('Method not allowed');
    }
};
const getSomething = async (req, res) => {
    const session = await getSession({ req });
    // console.log(session);
    if (session) {
        res.send({
            content: 'Welcome to the secret page',
        });
    } else {
        res.status(401).send({
            err: 'You need to be signed in.',
        });
    }
};

export default handler;

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
  • @brandon-han 感谢您提供解决方案。我在本地提出了相同的解决方案,但我不确定我对此有何感受。你有没有找到另一种方法来做到这一点?
  • @corysimmons 不,我没有找到任何其他解决方案。你认为这不是正确的方法吗?
  • 嘿@BrandonHan 我对相关的 Github 讨论发表了评论,并将链接放在这里供任何偶然发现此问题的人使用:github.com/nextauthjs/next-auth/discussions/…
【解决方案2】:

有一种特定的方法来处理来自 serverSideProps 的请求,比使用 useSession 更好(用于客户端请求)

https://next-auth.js.org/tutorials/securing-pages-and-api-routes#server-side

最佳使用 unstable_getServerSession 如文档示例中所述

await unstable_getServerSession(req, res, authOptions)

使用 authOptions 作为您的 [...nextauth].js 的导出

【讨论】:

    猜你喜欢
    • 2021-04-30
    • 2022-07-24
    • 2021-05-14
    • 1970-01-01
    • 2021-08-06
    • 2021-10-26
    • 2020-12-11
    • 2021-10-06
    • 2021-06-10
    相关资源
    最近更新 更多