NextJS Azure 服务(身份验证、SQL 数据库、存储帐户)集成问题

问题描述 投票:0回答:1

我正在尝试使用 服务构建一个 应用程序,该服务应仅可供我的 租户中的用户使用。我遇到的最大问题是数据库连接只能在静态 Web 应用程序模拟器 (localhost:4280) 上工作,而从存储帐户容器中提取数据只能在 localhost:3000 上工作。

当前资源

  • SQL 服务器
  • SQL 数据库
  • 存储账户
  • 静态网络应用程序
  • 应用程序已在 Microsoft Entra ID 中注册

我做的第一件事是设置静态 Web 应用程序并将其链接到生成 CI/CD 工作流程的存储库。接下来,我尝试解决数据库问题。我创建了一个

staticwebapp.database.config.json
文件。
当使用
swa start http://localhost:3000 --run 'npm run dev' --data-api-location swa-db-connection
启动应用程序时,我可以很好地看到从 SQL 数据库中提取的数据。

存储帐户才是真正混乱的地方。微软表示:

“要在 JavaScript 应用程序中使用 DefaultAzureCredential,请将 @azure/identity 包添加到您的应用程序中。”

// connect-with-default-azure-credential.js
import { BlobServiceClient } from '@azure/storage-blob';
import { DefaultAzureCredential } from '@azure/identity';
import 'dotenv/config'

const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME;
if (!accountName) throw Error('Azure Storage accountName not found');

const blobServiceClient = new BlobServiceClient(
  `https://${accountName}.blob.core.windows.net`,
  new DefaultAzureCredential()
);

尝试后,我发现

DefaultAzureCredential()
在浏览器中不起作用。您必须使用
InteractiveBrowserCredential
,它接受 clientId 和tenantId。我最终能够完成这项工作,但是当将部分移动到 NextJS API 路由以保护环境变量时,这就是我遇到的下一个问题。

当我尝试从模拟器 (localhost:4280) 获取 NextJS API 路由时,它在终端中给出一个块,指出“检测到功能请求,但未找到端点配置。请使用 --api-location 选项来配置函数端点。”如果我使用 localhost:3000,这些 API 路由调用就可以正常工作。

我的下一个问题是,当我使用 时,会出现弹出窗口,然后在我的终端中,我收到一条错误消息,指出

"Token issued for the Single-Page Application client-type may only be redeemed via cross-origin requests"

我希望实现的是实现 以预先对用户进行身份验证,然后尝试以无缝方式将该身份验证用于这些其他 Azure 服务。

我知道我在这里遇到了多个不同的问题,但任何朝正确方向的推动都会有很大帮助。我花了几天时间阅读文档并寻找资源,但我觉得我有点陷入困境。

提前谢谢您!

azure next.js azure-active-directory azure-blob-storage azure-ad-msal
1个回答
0
投票

此 Git issue 涉及在 Identity 中使用交互式浏览器凭据进行浏览器身份验证。如果提到默认 Azure 凭据,它会根据环境选择凭据,如Stack Overflow中所述。

使用

Azure.Identity
连接到 Azure Blob 存储的代码取自此 reference



import React, { useEffect, useState } from 'react';
import { InteractiveBrowserCredential } from '@azure/identity';
import { BlobServiceClient, BlobItem } from '@azure/storage-blob';

interface BlobViewProps {}

const BlobView: React.FC<BlobViewProps> = () => {
  const [blobsWeFound, setBlobsWeFound] = useState<BlobItem[]>([]);
  const [containerUrl, setContainerUrl] = useState<string>('');

  useEffect(() => {
    const signInOptions = {
      clientId: 'clientId', // Your application client ID
      tenantId: 'tenantId', // Your Azure AD tenant ID
    };

    const fetchBlobData = async () => {
      try {
        const blobStorageClient = new BlobServiceClient(
          'https://<your-storage-account-name>.blob.core.windows.net/',
          new InteractiveBrowserCredential(signInOptions)
        );

        const containerClient = blobStorageClient.getContainerClient('private');
        const blobList: BlobItem[] = [];

        for await (const blob of containerClient.listBlobsFlat()) {
          blobList.push(blob);
        }

        setBlobsWeFound(blobList);
        setContainerUrl(containerClient.url);
      } catch (error) {
        console.error('Error fetching blob data:', error);
      }
    };

    fetchBlobData();
  }, []);

  return (
    <div>
      <table>
        <thead>
          <tr>
            <th>blob name</th>
            <th>blob size</th>
            <th>download url</th>
          </tr>
        </thead>
        <tbody>
          {blobsWeFound.map((blob, index) => (
            <tr key={index}>
              <td>{blob.name}</td>
              <td>{blob.properties?.contentLength}</td>
              <td>
                <img src={`${containerUrl}${blob.name}`} alt={blob.name} />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

export default BlobView;


Next.js 文档应包含有关为 API 路由配置 CORS(跨源资源共享)的部分。这将启用应用程序前端 (localhost:4280) 和 API 路由 (localhost:3000) 之间的通信。

  • 参考此添加 CORS 以及 API 配置

  • MSAL的 Microsoft 文档。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.