在 NextJS 中获取 JWT 令牌 API

Get JWT token in NextJS API

我创建了一个与 Amazon Cognito 集成的 NextJS 应用程序。我有一个使用 Amplify Auth API(不是组件)的登陆页面。现在我需要调用一个外部的 API 来做 CRUD 操作。在 NextJS 中执行此操作的最佳方法是什么?

我想我会在 NextJS 中创建一个 API,它将请求转发到实际的外部 REST API。但我的问题是我无法在 API 上获取 JWT 令牌,因为它是后端代码。

这样的代码:

Auth.currentSession().then(data => console.log(data.accessToken.jwtToken));

显然行不通:

[DEBUG] 20:42.706 AuthClass - Getting current session
[DEBUG] 20:42.706 AuthClass - Failed to get user from user pool
[DEBUG] 20:42.707 AuthClass - Failed to get the current user No current user
(node:20724) UnhandledPromiseRejectionWarning: No current user

如何在 API 中获取令牌?

我已经使用 aws-cognito-next 库解决了这个问题。

根据 https://www.npmjs.com/package/aws-cognito-next 的文档,我创建了一个身份验证实用程序:

import { createGetServerSideAuth, createUseAuth } from "aws-cognito-next";
import pems from "../../pems.json"

// create functions by passing pems
export const getServerSideAuth = createGetServerSideAuth({ pems });
export const useAuth = createUseAuth({ pems });

// reexport functions from aws-cognito-next
export * from "aws-cognito-next";

pem文件是通过命令生成的(不用说,你必须先配置Amazon Cognito服务):

yarn prepare-pems --region <region> --userPoolId <userPoolId>

最后,在 NextJs API:

import {getServerSideAuth} from "../../src/utils/AuthUtils"

export default async (req, res) => {

  const initialAuth = getServerSideAuth(req)

  console.log("initialAuth ", initialAuth)

  if (initialAuth) {
    res.status(200).json({status: 'success'})

  } else {
    res.status(400).json({status: 'fail'})
  }
}

一个简单的方法是在您的应用中启用 ssrContext,Amplify 将向您的 api

提供用户凭据

在前端,例如 _app.tsx(或 app.js)

import Amplify, { Auth, API } from "aws-amplify";
import awsconfig from "../src/aws-exports";
Amplify.configure({...awsconfig, ssr: true});

然后在 api 中你可以简单地获取当前经过身份验证的 cognito 用户 例如 api/myfunction.tsx(或 js)

import Amplify, { withSSRContext } from "aws-amplify";
import awsExports from "../../src/aws-exports";
Amplify.configure({ ...awsExports, ssr: true });

/* @returns <CognitoUser>,OR null if not authenticated */
const fetchAuthenticatedUser: any = async (req: NextApiRequest) => {
  const { Auth } = withSSRContext({ req });
  try {
    let user = await Auth.currentAuthenticatedUser();
    return user;
  } catch (err) {    
    return null;
  }
}