如何通过next.js(with typeScript)应用调用身份验证的HTTP触发Google Cloud函数?

发布于 2025-01-24 20:09:14 字数 3162 浏览 4 评论 0原文

我创建了一个Google Cloud Platform帐户,并制作了一个简单的Hello_World类型Python“云功能”,该功能只是吐出一些简单的文本。我使此功能“ http”可访问,并且只能通过我为调用此函数的目的而被调用/认证的“服务帐户”。我为此“服务帐户”生成了一个密钥,并下载了密钥的JSON文件。

问题在于,我找不到有关如何使用我的服务帐户在next.js应用中调用此功能的任何文档。我尝试了一下:

import React from 'react';
import { Button } from 'react-bootstrap';
import { GoogleAuth } from 'google-auth-library';

const projectId = 'gtwitone';
const keyFilename = '/Users/<myusername>/path/to/cloudfunction/credentials.json';

class Middle extends React.Component {
    handleClick() {
        console.log('this is:', this);
      }
    // This syntax ensures `this` is bound within handleClick.  // Warning: this is *experimental* syntax.  handleClick = () => {    console.log('this is:', this);  }

    /* async listFunctions() {
        const [functions] = await client.listFunctions();
        console.info(functions);
    } */

    async runGoogleCloudFunctionTest() {
      // Define your URL, here with Cloud Run but the security is exactly the same with Cloud Functions (same underlying infrastructure)
      const url = "https://us-central1-<projectname>.cloudfunctions.net/<functionname>"
      //Example with the key file, not recommended on GCP environment.
      const auth = new GoogleAuth({keyFilename: keyFilename})
  
      //Create your client with an Identity token.
      const client = await auth.getIdTokenClient(url);
      const res = await client.request({url});
      console.log(res.data);
    }

    render() {
      return (
        <div className="col-md-12 text-center">
            <Button variant='primary' onClick={this.runGoogleCloudFunctionTest}>
                Click me
            </Button>
        </div>
      );
    }
  }

export default Middle;

但是我在终端中遇到了这个错误:

<myusername>@<mycomputername> <thisnextjsappdirectory> % yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait  - compiling...
event - compiled client and server successfully in 267 ms (124 modules)
wait  - compiling / (client and server)...
wait  - compiling...
error - ./node_modules/google-auth-library/build/src/auth/googleauth.js:17:0
Module not found: Can't resolve 'child_process'

Import trace for requested module:
./node_modules/google-auth-library/build/src/index.js
./components/Middle.tsx
./pages/index.tsx

https://nextjs.org/docs/messages/module-not-found
Native Node.js APIs are not supported in the Edge Runtime. Found `child_process` imported.

Could not find files for / in .next/build-manifest.json
Could not find files for / in .next/build-manifest.json
^C
<myusername>@<mycomputername> <thisnextjsappdirectory> % 

我知道这是服务器端在我的下一个应用程序中渲染的问题,人们建议使用这样的客户端软件包 https://github.com/google/google-google-api-javascript-client 。但是Google-api-javascript-client没有任何有关使用.json凭据文件进行身份验证的文档没有。

简而言之,我该如何使用.json AM身份验证的服务帐户的凭证文件运行并运行Google Cloud功能?

I created a Google Cloud Platform account, and made a simple hello_world type Python "Cloud Function" that just spits out some simple text. I made this function "HTTP" accessible and only able to be called/authenticated by a "Service Account" that I made for the purpose of calling this very function. I generated a key for this "Service Account" and downloaded the json file for the key.

The problem is that I can't find any documentation on how to call this function with my service account in a next.js app. I tried this:

import React from 'react';
import { Button } from 'react-bootstrap';
import { GoogleAuth } from 'google-auth-library';

const projectId = 'gtwitone';
const keyFilename = '/Users/<myusername>/path/to/cloudfunction/credentials.json';

class Middle extends React.Component {
    handleClick() {
        console.log('this is:', this);
      }
    // This syntax ensures `this` is bound within handleClick.  // Warning: this is *experimental* syntax.  handleClick = () => {    console.log('this is:', this);  }

    /* async listFunctions() {
        const [functions] = await client.listFunctions();
        console.info(functions);
    } */

    async runGoogleCloudFunctionTest() {
      // Define your URL, here with Cloud Run but the security is exactly the same with Cloud Functions (same underlying infrastructure)
      const url = "https://us-central1-<projectname>.cloudfunctions.net/<functionname>"
      //Example with the key file, not recommended on GCP environment.
      const auth = new GoogleAuth({keyFilename: keyFilename})
  
      //Create your client with an Identity token.
      const client = await auth.getIdTokenClient(url);
      const res = await client.request({url});
      console.log(res.data);
    }

    render() {
      return (
        <div className="col-md-12 text-center">
            <Button variant='primary' onClick={this.runGoogleCloudFunctionTest}>
                Click me
            </Button>
        </div>
      );
    }
  }

export default Middle;

But I got this error in my terminal:

<myusername>@<mycomputername> <thisnextjsappdirectory> % yarn dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait  - compiling...
event - compiled client and server successfully in 267 ms (124 modules)
wait  - compiling / (client and server)...
wait  - compiling...
error - ./node_modules/google-auth-library/build/src/auth/googleauth.js:17:0
Module not found: Can't resolve 'child_process'

Import trace for requested module:
./node_modules/google-auth-library/build/src/index.js
./components/Middle.tsx
./pages/index.tsx

https://nextjs.org/docs/messages/module-not-found
Native Node.js APIs are not supported in the Edge Runtime. Found `child_process` imported.

Could not find files for / in .next/build-manifest.json
Could not find files for / in .next/build-manifest.json
^C
<myusername>@<mycomputername> <thisnextjsappdirectory> % 

I know that this is problem with server side rendering in my Next.js app and people recommend using a client side package like this https://github.com/google/google-api-javascript-client. But google-api-javascript-client doesn't have any documentation on authenticating with a .json credentials file instead of an API KEY which I do not have.

In short how do I get my app to work and run the Google Cloud function with a .json credentials file for am authenticated service account?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

儭儭莪哋寶赑 2025-01-31 20:09:14

我通过简单地将googleauth api调用到pags/api路由来修复它。

页面/api/google.ts

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"
import { GoogleAuth } from "google-auth-library"

export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
    const url = process.env.FUNCTION_URL as string

    //Example with the key file, not recommended on GCP environment.
    const auth = new GoogleAuth({ keyFilename: process.env.KEYSTORE_PATH })

    //Create your client with an Identity token.
    const client = await auth.getIdTokenClient(url)
    const result = await client.request({ url })
    console.log(result.data)
    res.json({ data: result.data })
}

组件/midder.tsx

import React from "react"
import { Button } from "react-bootstrap"

class Middle extends React.Component {
  handleClick() {
        console.log("this is:", this)
    }
  
  // this talks with /pages/api/google
  async imCallingAnAPI() {
    const result = await fetch("/api/google")
    console.log({ result })
  }

  render() {
    return (
      <div className="col-md-12 text-center">
        <Button variant="primary" onClick={this.imCallingAnAPI}>
          Click me
        </Button>
      </div>
    )
  }
}

export default Middle

页/index.tsx

import type { NextPage } from 'next'
import Header from '../components/Header';
import Footer from '../components/Footer';
import Middle from '../components/Middle';

const Home: NextPage = () => {
  return (
    <><main className='d-flex flex-column min-vh-100'>
      <Header />
      <br></br>
      <br></br>
      <Middle />
      </main>
      <footer>
        <Footer />
      </footer>
    </>
  )
}

export default Home

我认为Next.js在组件中加载googleauth很难。我不是100%确定为什么,但是我认为这与Next.js有关。js不知道如何使用服务器端渲染处理googleauth

I fixed it by simply moving the GoogleAuth api call to the pages/api route.

pages/api/google.ts

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from "next"
import { GoogleAuth } from "google-auth-library"

export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
    const url = process.env.FUNCTION_URL as string

    //Example with the key file, not recommended on GCP environment.
    const auth = new GoogleAuth({ keyFilename: process.env.KEYSTORE_PATH })

    //Create your client with an Identity token.
    const client = await auth.getIdTokenClient(url)
    const result = await client.request({ url })
    console.log(result.data)
    res.json({ data: result.data })
}

components/Middle.tsx

import React from "react"
import { Button } from "react-bootstrap"

class Middle extends React.Component {
  handleClick() {
        console.log("this is:", this)
    }
  
  // this talks with /pages/api/google
  async imCallingAnAPI() {
    const result = await fetch("/api/google")
    console.log({ result })
  }

  render() {
    return (
      <div className="col-md-12 text-center">
        <Button variant="primary" onClick={this.imCallingAnAPI}>
          Click me
        </Button>
      </div>
    )
  }
}

export default Middle

pages/index.tsx

import type { NextPage } from 'next'
import Header from '../components/Header';
import Footer from '../components/Footer';
import Middle from '../components/Middle';

const Home: NextPage = () => {
  return (
    <><main className='d-flex flex-column min-vh-100'>
      <Header />
      <br></br>
      <br></br>
      <Middle />
      </main>
      <footer>
        <Footer />
      </footer>
    </>
  )
}

export default Home

I think that next.js has trouble loading GoogleAuth in a component. I'm not 100% sure why, but I think it has to do with next.js not knowing exactly how to handle GoogleAuth with server-side rendering.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文