NextJS -使用eswr与令牌从会话



我正在使用NextJS, Next-auth和Django作为后端。我使用凭据提供程序对用户进行身份验证。用户在Django后端进行身份验证,用户信息和access令牌一起存储在会话中。
我正在尝试使用useSWR现在从后端获取数据。(这个页面不需要预加载,这就是为什么我正在使用SWR)我需要从useSWR的fetcher方法中从会话发送访问
_token。但是我不知道在会话被验证后如何使用useSWR。也许我需要另一种方法。

我试图等待会话被验证,然后用useSWR发送请求,但我得到这个错误:**错误:呈现更多的钩子比以前的呈现期间。
**
有没有人能提供一个更好的方法来处理这个问题?我基本上需要的是确保从自定义后端接收到的访问令牌包含在Authorization Header中的每个请求中。我试图在NextJS, Next-Auth或SWR的文档中找到一些东西,但我只找到了在会话中存储自定义access_token的方法,而不是如何将其包含在以下后端请求的Header中。

这是组件的代码:

import { useSession } from "next-auth/react";
import useSWR from 'swr';
import axios from 'axios'
export default function Profile() {
const { data: session, status } = useSession();
// if session is authenticated then fetch data
if (status == "authenticated") {
// create config with access_token for fetcher method
const config = {
headers: { Authorization: `Bearer ${session.access_token}` }
};
const url = "http://mybackend.com/user/"
const fetcher = url => axios.get(url, config).then(res => res.data)
const { data, error } = useSWR(url, fetcher)
}
if (status == "loading") {
return (
<>
<span>Loading...</span>
</>
)
} else {
return (
<>
{data.email}
</>
)
}
}

您不需要每次都检查status。您需要做的是将function添加到您的app.js文件

function Auth({ children }) {
const router = useRouter();
const { status } = useSession({
required: true,
onUnauthenticated() {
router.push("/sign-in");
},
});
if (status === "loading") {
return (
<div> Loading... </div>
);
}
return children;
}

然后将auth属性添加到需要session的每个页面

Page.auth = {};

最后更新你的const App像这样

<SessionProvider session={pageProps.session}>
<Layout>
{Component.auth ? (
<Auth>
<Component {...pageProps} />
</Auth>
) : (
<Component {...pageProps} />
)}
</Layout>
</SessionProvider>

所以每个有.auth的页面都将被auth组件包裹,这将为它完成工作

现在摆脱所有的if语句检查session是否被定义,因为只有当session在这里时你的页面才会呈现

多亏了@Ahmed Sbai,我才得以成功。组件现在看起来像这样:

import { useSession } from "next-auth/react";
import axios from "axios";
import useSWR from 'swr';
Profile.auth = {}
export default function Profile() {
const { data: session, status } = useSession();
// create config with access_token for fetcher method
const config = {
headers: { Authorization: `Bearer ${session.access_token}` }
};
const url = "http://mybackend.com/user/"
const fetcher = url => axios.get(url, config).then(res => res.data)
const { data, error } = useSWR(url, fetcher)
if (data) {
return (
<>
<span>{data.email}</span>
</>
)
} else {
return (
<>
Loading...
</>
)
}
}

应用组件和功能:

function Auth({ children }) {
const router = useRouter();
const { status } = useSession({
required: true,
onUnauthenticated() {
router.push("/api/auth/signin");
},
});
if (status === "loading") {
return (
<div> Loading... </div>
);
}
return children;
}
function MyApp({
Component,
pageProps: { session, ...pageProps },
}) {
return (
<SessionProvider session={pageProps.session}>
{Component.auth ? (
<Auth>
<Component {...pageProps} />
</Auth>
) : (
<Component {...pageProps} />
)}
</SessionProvider>
)
}

最新更新