V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
c3de3f21
V2EX  ›  前端开发

Q: 关于 nuxt3/nuxt3ui/@apollo_client/hasura 的一些问题?

  •  
  •   c3de3f21 · 100 天前 · 478 次点击
    这是一个创建于 100 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Intro

    无场景,就是做做看,试试 API 随便写写,现在有几个问题想请教各位仁兄

    Env

    • nuxt3
    • @nuxt/ui
    • @apollo/client
    • docker
    • docker - pgsql
    • docker - hasura

    Code

    Nitro

    现在我通过

    
    export default defineNitroPlugin((nitroApp) => {
      const link = new HttpLink({
        uri: 'http://localhost:8080/v1/graphql',
        headers: {
          'x-hasura-admin-secret': '123456'
        }
      });
      const apolloClient = new ApolloClient({
        cache: new InMemoryCache(),
        link: link
      });
      nitroApp.hooks.hook('request', (event) => {
        event.context.apollo = apolloClient
      })
    })
    
    ------------------------Handler---------------------------------
    
    import { gql } from '@apollo/client/core'
    
    export default defineEventHandler(async (event) => {
      const client = event.context.apollo
      const query = gql`
        query getUser($limit: Int!) {
          User(limit: $limit) {
            id
            name
          }
          User_aggregate {
            aggregate {
              count
            }
          }
        }
      `
      const { limit } = await readBody(event)
      try {
        const { data } = await client.query({ query, variables: { limit: 10 } })
        return data
      } catch (error) {
        console.error('GraphQL query error:', error)
        return { error: 'Failed to fetch data' }
      }
    })
    
    

    连接本地的 Hasura 服务,Hasura 是动态管理 GraphQL 的 Schema 的一个服务,这个服务我链接了 PGSQL ,具体的环境如下

    version: '3.6'
    
    services:
      postgres:
        image: postgres:16.3
        restart: always
        environment:
          POSTGRES_USER: root
          POSTGRES_PASSWORD: root
          POSTGRES_DB: rm00
        ports:
          - "5432:5432"
        volumes:
          - ./postgres:/var/lib/postgresql/data
    
      hasura:
        restart: always
        image: hasura/graphql-engine:v2.15.2
        ports:
          - "8080:8080"
        depends_on:
          - postgres
        environment:
          HASURA_GRAPHQL_DATABASE_URL: postgres://root:root@postgres:5432/rm00
          HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
          HASURA_GRAPHQL_ENABLE_ALLOWLIST: "true"
          HASURA_GRAPHQL_ADMIN_SECRET: 123456
    
    

    Nuxt 的前台

    <template>
      <div>
        <h1>Login</h1>
        <div v-if="data">
          {{ data }}
        </div>
        {{ error }}
      </div>
    </template>
    
    
    <script lang="ts" setup>
    
    definePageMeta({
      layout: 'blank',
      auth: 'guest'
    })
    
    const { data, error, execute } = useFetch('/api/demo', {
      method: 'post',
      auth: false
    })
    </script>
    

    整个 demo 跑通了是跑通了,但是总觉得不是一个很好的方式或者说不成熟,现在有几个问题想请教请教大佬们

    Question

    • 关于 GraphQL 用于不用好用与不好用的问题暂且不讨论,这里就是要用
    • 1.我试着使用 @nuxtjs/apollo ,但是 secret 会混入请求头也就是有注入风险,这里不明白这个 @nuxtjs/apollo 项目的用意,或者我应该配合 auth 使用?请问如何配合 auth 服务?
    • 2.由于第一个问题我将查询写到了后台也就是 nitro 的 server 中,这样是否妥善?
    • 3.有没有更好的方式,方案,能让我用 js/ts 走完整个开发流程?
    3 条回复    2024-08-16 09:16:14 +08:00
    c3de3f21
        1
    c3de3f21  
    OP
       100 天前
    额,沉了。。。
    rocmax
        2
    rocmax  
       91 天前   ❤️ 1
    hasura 的 admin secret 最好不要用来请求 API ,因为会直接跳过所有权限检查。admin 留着登陆管理后台比较好。
    hasura 有基于角色的权限管理,但是角色信息需要从外部获得,可以参考一下 authentication 文档,有和多种认证服务连接的例子,hasura 有两种取得 role 的方式:
    1. 从请求头中取得含有 role 信息的 jwt ( hasura 会取得认证服务的公钥进行验证),这种情况下需要客户端先从认证服务器取得 jwt 并附加在请求头中(例如 keycloak )
    2. hasura 将请求转发至认证服务器并从 response 中取得 role 信息,然后根据 role 信息完成查询将结果返回给客户端,这种情况可能需要自建认证服务器用以返回 hasura 需要的数据格式(例如 aws congnito )

    我理解你用 api 服务端隔离了前端来的请求和 hasura ,由 api 服务端添加认证 header 后传递给 hasura 对吗?按道理只要保证 secret 不离开后端应该没有什么风险,不过即使这样也不推荐直接用 admin secret 。

    我不太理解 “secret 会混入请求头也就是有注入风险”,具体解释一下的话我或许可以给你答案。
    c3de3f21
        3
    c3de3f21  
    OP
       90 天前
    @rocmax 感谢老哥解答

    解释:就是假如前端直接对 hasura 的 api 请求头就使用了 secret ,造成 secret 暴露了,所以才换到后端做一个中间层。

    不过现在已经换了方式了,换成 prisma 了。还挺好使。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3447 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:45 · PVG 08:45 · LAX 16:45 · JFK 19:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.