SSR: 하수라를 가진 점원

이 문서는 next.js에서 clerk(withServerSideAuth)로 서버 측 렌더링(인증)을 달성하는 데 도움이 될 것입니다.

Clerk
합법적인 사용자가 애플리케이션에 액세스하고 인증된 요청을 할 수 있도록 Clerk를 통해 여러 인증 전략을 사용할 수 있습니다.

Nextjs 및 Clerk와 함께 SSR로
서버 측 렌더링을 활성화하기 위해 Nextjs는 getServerSideProps라는 특수 내보내기를 사용합니다. 점원의 WithServerSideAuth 도우미는 인증 싱글톤으로 채워집니다.

단계:
  • Apollo 클라이언트 설정
  • ssr에 대해 getServerSideProps 및 withServerSideAuth 사용
  • graphql 쿼리 사용
  • 인증된 사용자와 인증되지 않은 사용자 모두에 대한 테스트
  • 쿼리가 로그인 후에만 응답하는 조건이 있는 경우 아무 것도 반환하지 마십시오. 그렇지 않으면 문제가 발생할 수 있습니다
  • .

    동일한 코드 조각:


    1.apolloclient 설정:


    import { useMemo } from 'react';
    import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
    import merge from 'deepmerge';
    import isEqual from 'lodash/isEqual';
    
    let apolloClient;
    const uri = process.env.NEXT_PUBLIC_HASURA_URI;
    function createApolloClient(headers) {
      return new ApolloClient({
        ssrMode: typeof window === 'undefined', // set to true for SSR
        link: createHttpLink({
          uri,
          credentials: 'same-origin',
          headers: {
            Apitoken: process.env.YOUR_API_TOKEN,
          },
        }),
        cache: new InMemoryCache({
          typePolicies: {
            Query: {
              fields: {
                feed: {
                  keyArgs: ['strategy', 'limit', 'gt_token'],
                  // Concatenate the incoming list items with
                  // the existing list items.
                  merge(existing = [], incoming) {
                    const result = Object.assign({}, incoming);
                    if (existing?.hits) {
                      result.hits = [...existing.hits, ...incoming.hits];
                    }
                    return result;
                  },
                },
                experts: {
                  keyArgs: ['limit'],
                  // Concatenate the incoming list items with
                  // the existing list items.
                  merge(existing = [], incoming) {
                    const result = Object.assign({}, incoming);
                    if (existing?.hits) {
                      result.hits = [...existing.hits, ...incoming.hits];
                    }
                    return result;
                  },
                },
              },
            },
          },
        }),
      });
    }
    
    export function initializeApollo(initialState = null, ctx) {
      const headers = ctx?.headers ?? {};
      const _apolloClient = apolloClient ?? createApolloClient(headers);
    
      // If your page has Next.js data fetching methods that use Apollo Client,
      // the initial state gets hydrated here
      if (initialState) {
        // Get existing cache, loaded during client side data fetching
        const existingCache = _apolloClient.extract();
    
        // Restore the cache using the data passed from
        // getStaticProps/getServerSideProps combined with the existing cached data
        const data = merge(initialState, existingCache, {
          // combine arrays using object equality (like in sets)
          arrayMerge: (destinationArray, sourceArray) => [
            ...sourceArray,
            ...destinationArray.filter((d) =>
              sourceArray.every((s) => !isEqual(d, s))
            ),
          ],
        });
        _apolloClient.cache.restore(data);
      }
    
      // For SSG and SSR always create a new Apollo Client
      if (typeof window === 'undefined') return _apolloClient;
    
      // Create the Apollo Client once in the client
      if (!apolloClient) apolloClient = _apolloClient;
      return _apolloClient;
    }
    
    export function useApolloHasura(initialState) {
      return useMemo(
        () => initializeApollo(initialState, undefined),
        [initialState]
      );
    }
    


    2. ssr에 대해 getServerSideProps 및 withServerSideAuth 사용:


    import { initializeApollo } from '../apolloClient';
    import { withServerSideAuth } from '@clerk/nextjs/ssr';
    
    export const getServerSideProps = withServerSideAuth(
      async (ctx) => {
       const { getToken } = ctx.req.auth;
        const token = await getToken({ template: 'hasura' });
        const apolloClient = initializeApollo(null, ctx);
    
       const client = initialApollo(null, ctx);
        const sub =
          (await client.query({
            query: YOUR_QUERY,
            context: {
              headers: {
                authorization: 'YOUR_AUTHORIZATION_TOKEN',
              },
            },
          }));
    
        const status = sub?.data;
    
           return {
          props: {
            isStatus: status,
          },
        };
      },
      { loadUser: true }
    );
    


    3. 쿼리가 로그인한 후에만 응답하는 조건:

    다음은 인증된 사용자 예제 구독 쿼리에 대해서만 응답을 제공하는 쿼리 스니펫입니다. 위 코드를 약간 변경해야 합니다. 토큰(hasuraToken)이 인증되지 않은 사용자에 대해 아무것도 반환하지 않는 경우 상태가 정의되지 않음을 반환하므로 이 경우 아래와 같이 null을 반환해야 합니다.

      const sub =
          token !== null &&
          (await client.query({
            query: PAYMENTS,
            context: {
              headers: {
                authorization: `Bearer ${token}`,
              },
            },
          }));
    
       const status = sub?.data;
    
       return {
          props: {
            isStatus: status === undefined ? null : status
          },
        };
    
    
    


    자세한 내용은 ClerkNextjs with SSR example을 참조하십시오.

    이것에 대해 어떻게 생각하세요? 내가 언급하지 않은 다른 방법이 있습니까? 아래 댓글로 알려주세요. 빨리 듣고 싶어요. 감사

    Happy Coding!!

    좋은 웹페이지 즐겨찾기