NextJS 및 Firebase를 사용한 서버측 인증


개술
Firebase 및 Next에 사용자 승인을 추가할 수 있는 좋은 방법을 찾습니다.js 응용 프로그램이 가장 쉽게 찾을 수 없습니다.그래서 나는 내가 짜 맞추는 과정을 설명하고 다른 사람들도 도울 수 있는 강좌를 한 편 쓸 것이라고 생각한다.
이 방법의 장점은 모든Firebase 인증은 서버에서 이루어지기 때문에 모든 요청에 필요한 사용자 데이터가 있습니다.
권한과 보호된 루트를 가지고 싶으면, 이 방식은 _app.js 파일에 있기 때문에 모든 페이지에서 사용자 인증 검사를 할 수 있습니다.특정 페이지에서만 이 라우트를 사용하려면 해당 페이지에 getInitialProps 기능을 추가해야 합니다.
사용자가 로그인할 때 Firebase 토큰을 만들고 다음을 사용합니다.js API 라우팅은 각 페이지에서 요청한 라이센스 토큰인지 확인할 수 있습니다.그 다음에 사용자 데이터는 페이지의 다른 구성 요소에 사용할 수 있도록 페이지 단계에서 사용할 수 있습니다.
우리는 다음 기회를 이용할 것이다.js 기능getInitialProps.이것은 갈고리나 클래스 생명주기 방법의 전형적인 API 데이터 호출을 기다리는 대신 채워진 데이터로 페이지를 보여 줍니다.이것은 불러오는 시간을 가속화하고 페이지를 불러올 때 사용자 데이터를 확보합니다.
다음 단계에 나는 이 두 방면의 기본 지식에 대해 모두 익숙하다고 가정할 것이다.js와 Firebase.useEffect 파일이나 _app.js 노선의 세부 사항에 대해 궁금한 것이 있으면 언제든지 물어보세요.
자, 시작합시다.

프로세스
우선, 우리는 api/validate 파일을 만들어야 한다.이것은 모든 사용자 데이터와Firebase 함수를 위한 상하문 제공 프로그램을 만드는 곳입니다.React Context API를 사용해 본 적이 없다면basictutorial를 써서 더 많은 설명을 해 드리겠습니다.
여기에 멈추고 상하문을 통해 사용자 데이터를 전달할 수 있지만, 이것은 다음 페이지를 사용하지 않고 모든 페이지에 불러오는 시간이 있다는 것을 의미합니다.js 기능UserContext.js.
우리는 잠시 후에 이것들을 함께 놓을 것이다.그러나 현재 getInitialProps 파일은 다음과 유사해야 합니다.
이제 로그인 기능만 있지만 로그아웃, 등록 또는 다른 Firebase 기능을 추가할 수도 있습니다.나는 여기에서 사용자 인증 함수를 보존하고 위아래 문장을 통해 적당한 구성 요소에 전달하는 것을 좋아한다.
Google은 js 쿠키를 사용하여 쿠키를 만들고 삭제할 것입니다.
다음과 같은 방법으로 설치할 수 있습니다.
yarn add js-cookie
import React, { useEffect, useState } from 'react';

import cookie from 'js-cookie';
import firebase from '../firebaseSetup';

export const UserContext = React.createContext();

const tokenName = 'firebaseToken';

const UserProvider = ({ children }) => {
  // Basic Firebase email login function.
  const emailLogin = async (email, password, redirectPath) => {
    await firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(() => {
        console.log('User logged in.');
      })
      .catch((err) => {
        console.log(err);
      });
  };

  // Checks that user state has changed and then creates or destroys cookie with Firebase token.
  const onAuthStateChange = () => {
    return firebase.auth().onAuthStateChanged(async (user) => {
      if (user) {
        const token = await user.getIdToken();
        cookie.set(tokenName, token, { expires: 14 });
      } else {
        cookie.remove(tokenName);
      }
    });
  };

  useEffect(() => {
    const unsubscribe = onAuthStateChange();
    return () => {
      unsubscribe();
    };
  }, []);

  return <UserContext.Provider value={{ emailLogin }}>{children}</UserContext.Provider>;
};

export default UserProvider;
이곳의 마력은 이 부분에 있다.
// Add or remove cookie with Firebase Auth Token on sign in or logout.
const onAuthStateChange = () => {
  return firebase.auth().onAuthStateChanged(async (user) => {
    if (user) {
      const token = await user.getIdToken();
      cookie.set(tokenName, token, { expires: 14 });
    } else {
      cookie.remove(tokenName);
    }
  });
};

useEffect(() => {
  const unsubscribe = onAuthStateChange();
  return () => {
    unsubscribe();
  };
}, []);
여기서UserContext.jsonAuthStateChange 갈고리라고 불린다.Firebase 인증 토큰을 저장하는 쿠키에 로그인하거나 사용자가 로그아웃하면 쿠키가 삭제됩니다.우리는 다음 주에 이 지폐를 검사할 것이다.JSAPI는 페이지를 로드하기 전에 서버에서 라우팅하고 사용자 인증을 수행합니다.이것은 Firebase의 사용자 인증을 기다리지 않고 불러오는 시간을 차지할 수 있도록 합니다.
현재 useEffect에서 우리는 우리의 초기 아이템을 획득할 수 있습니다.우리는 다음 함수를 호출하기 위해 _app.js 함수를 추가해야 한다.js API 라우팅 및 사용자 데이터 반환
Google은 "동구미식각"에서 얻은 데이터와 cookies, 그리고 이 파일의 다음 cookies를 사용할 것입니다. 이 cookies는 다음과 같이 추가할 수 있습니다.
yarn add isomorphic-unfetch next-cookies
파일을 가져와야 합니다getInitialProps.
MyApp.getInitialProps = async (appContext) => {
  const { ctx } = appContext;
  // Calls `getInitialProps` and fills `appProps.pageProps`
  let error;
  const appProps = await App.getInitialProps(appContext);

  const { firebaseToken } = cookies(ctx);

  // If token exists run Firebase validation on server side before rendering.
  if (firebaseToken) {
    try {
      const headers = {
        'Context-Type': 'application/json',
        Authorization: JSON.stringify({ token: firebaseToken }),
      };
      const result = await fetch(`${server}/api/validate`, { headers }).then((res) => res.json());
      return { ...result, ...appProps };
    } catch (e) {
      console.log(e);
    }
  }
  return { ...appProps };
};
올바른 서버를 프로덕션 및 개발에 사용하려면 다음과 같은 방법을 사용할 수 있습니다.
const dev = process.env.NODE_ENV === 'development';

const server = dev ? 'http://localhost:3000' : 'https://mydomain.com/';
마지막 일은 모든 일을 연결하는 것이다.지금 우리는 다음 것을 추가해야 한다.JSAPI 라우팅페이지 폴더에 _app.js 파일을 만들어야 합니다.나는 네가 다음 단계를 많이 이해할 것을 강력히 건의한다.다음 SSR 기능을 활용하는 데 확실히 도움이 되는 js API 라우팅js 제공.
여기서 Firebase 데이터로 페이지를 채우는 논리를 만들 것입니다.
  • 여기에 주의사항이 하나 있습니다. Firebase 관리 실례를 만들어야 사용할 수 있습니다. 표준적인Firebase 실례를 간단하게 사용할 수 없습니다.
  • import { firebaseAdmin } from '../../utilities/firebaseAdminSetup';
    
    const validate = async (token) => {
      // Check that the user has a valid token
      const decodedToken = await firebaseAdmin.auth().verifyIdToken(token, true);
      let userData;
      // Get user Firebase data from token
      const user = await firebaseAdmin.auth().getUser(decodedToken.uid);
      // Get any additional user data from the Firebase DB
      await firebaseAdmin
        .firestore()
        .collection('users')
        .doc(decodedToken.uid)
        .get()
        .then((doc) => {
          if (doc.exists) {
            userData = { ...doc.data() };
          }
        })
        .catch((error) => {
          console.log('Error getting document:', error);
        });
      // Assign the user result that will be passed to your _app.js file with populated data from the getUser and db functions
      const result = {
        user: {
          uid: user.uid,
          email: user.email,
          username: userData.username,
          emailVerified: user.emailVerified,
        },
      };
      return result;
    };
    
    export default async (req, res) => {
      try {
        // Check if there is a token and if not return undefined.
        const { token } = JSON.parse(req.headers.authorization || '{}');
        if (!token) {
          return res.status(403).send({
            errorCode: 403,
            message: 'Auth token missing.',
          });
        }
        // Call the validate function above that gets the user data.
        const result = await validate(token);
        return res.status(200).send(result);
      } catch (err) {
        // Return undefined if there is no user. You may also send a different status or handle the error in any way that you wish.
        console.log(err);
        const result = undefined;
        return res.status(200).send(result);
      }
    };
    
    당신은 현재 api/validate.js 모든 페이지 경로에서 도구로 사용할 수 있습니다.user 파일의 도구로 어셈블리에 전달하기만 하면 됩니다.사용자 인증은 현재 매우 간단해서 다른 구성 요소에 사용할 수 있습니다.
    이 모드는 실행하고자 하는 모든 서버 측의 데이터를 얻는 데 매우 편리합니다.이것은 넥스트의 큰 특색이다.js, 프로그램 전체에서 사용해 보십시오.

    좋은 웹페이지 즐겨찾기