如何将授权令牌传递给Next.js 13中的服务器组件(包含app目录)?

rekjcdws  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(107)

我是Next.js的新手,正在客户端React上下文中存储JWT授权令牌,并希望将该令牌从客户端上下文中“传递”到服务器组件,以便可以通过headers()cookies()函数从服务器组件检索该令牌。
我假设我需要在客户端代码上“设置”这些头文件和cookie,但是怎么做呢?
我更喜欢使用headers(),因为我可以控制何时/是否发送凭据;对于cookie,我假设它总是与每个请求一起发送。
Next.js 13的稳定版本有一个Authentication文档,但我是从不使用getServerSideProps()的app目录(beta)版本开始的。
稳定文档还提到了iron-session,我在Next.js 13中的一个如何读取cookie的示例中发现了这个问题,但它没有显示如何设置它。

tl;dr 如何在客户端设置头文件和cookie,以便可以通过服务器组件中的headers()cookies()函数读取它们?

bjp0bcyl

bjp0bcyl1#

  • 当用户登录时,您将凭据发送到pages/api/auth/login。您检查验证并创建令牌。

我使用cookies-next库来处理cookie。

import { setCookie } from "cookies-next";

export default async function handler(req: NextApiRequest,res: NextApiResponse)
 {
  // pass all the checking
  const token = await jwt.sign(credentials,secret)
  setCookie("jwt", token, { req, res, maxAge: 60 * 60 * 24 });
}
  • 每次发出请求时,都将令牌附加到报头。

使用cookies-next

import { getCookie } from "cookies-next";

  const jwt = getCookie("jwt");

 const response = await axios.get(`${process.env.BASE/whatever}`, {
    headers: {
      Authorization: `Bearer ${jwt}`,
    },
  });
  • 以前在服务器端函数中,我们可以访问req对象并检查用户是否经过身份验证。为了在next.js中处理此问题,我创建了一个端点api/auth/me。我向此端点发送了一个请求,以检查用户是否具有有效的jwt。我必须在app目录的顶层组件中执行此操作。我创建了一个Authentication Context,并在useEffect中检查用户的状态。

在身份验证上下文中,客户端组件

const fetchUser = async () => {
    setAuthState({
      data: null,
      error: null,
      loading: true,
    });
    try {
      const jwt = getCookie("jwt");

      if (!jwt) {
        return setAuthState({
          data: null,
          error: null,
          loading: false,
        });
      }

      const response = await axios.get(`${process.env.BASE/api/auth/me}`, {
        headers: {
          Authorization: `Bearer ${jwt}`,
        },
      });

      setAuthState({
        data: response.data,
        error: null,
        loading: false,
      });
    } catch (error: any) {
      setAuthState({
        data: null,
        error: error.response.data.errorMessage,
        loading: false,
      });
    }
  };

   useEffect(() => {
     fetchUser();
   }, []);
  • 这是pages/api/auth/me端点。

我在auth上下文中发出请求

export default async function handler(req: NextApiRequest,res: NextApiResponse)
 {
  const bearerToken = req.headers["authorization"] as string;
  const token = bearerToken.split(" ")[1];

  const payload = jwt.decode(token) as { email: string };

  if (!payload.email) {
    return res.status(401).json({
      errorMessage: "Unauthorized request",
    });
  }

  const user = yourFetchUser(payload.email)

  if (!user) {
    return res.status(401).json({
      errorMessage: "User not found",
    });
  }

  return res.json({...user});
}
  • 检查用户是否在导航栏中通过身份验证。

这是一个客户端组件

const { data, loading } = useContext(AuthenticationContext);

根据您设置的数据有条件地显示用户名或登录按钮。

  • 最后,使用cookies-next注销非常简单
import { removeCookies } from "cookies-next";

removeCookies("jwt");

相关问题