본문 바로가기

리뷰&생각

다큐사우르스에 포켓베이스 로그인 기능 붙이기

 

 

시스템의 매뉴얼을 제공할 때 많이 사용하는 다큐사우르스 솔루션입니다. 노드js 기반으로 설치해서 사용할 수 있고, 마크다운(md) 포맷의 문서를 넣으면 자동으로 매뉴얼과 같이 동작합니다. 매우 마음에 드는 시스템인데 비공개 매뉴얼을 만드는데에는 부족한 부분이 있습니다. 

 

검색해서 비공개 매뉴얼을 운영하는 방법을 찾았고, 로컬에서 적용해 보니 잘 되네요. 내용을 정리했습니다. 

 

우선 다큐사우르스를 설치합니다. https://docusaurus.io/ko/docs/installation

 

설치 | Docusaurus

도큐사우루스를 로컬에 설치하고 즉시 도큐사우루스 사이트를 시작하는 방법

docusaurus.io

 

다음 링크에 있는 사이트의 소스를 적용해야 합니다. https://www.fastpocket.dev/blogs/how-to-add-authentication-to-docusaurus

 

How To Add Authentication To Docusaurus | FastPocket

Adding authentication to Docusaurus is easy using swizzling

www.fastpocket.dev

 

구조를 먼저 잡기 위해 src 폴더 아래에 theme 폴더를 만들고, 그 속에 ColorModeToggle 폴더를 만듭니다. 

src

  - theme

     - ColorModeToggle

 

총 3개의 js 파일을 만들어 넣어야 합니다. 

 

Root.js 파일은 theme 폴더에 배치합니다.

 

import React, { useState } from "react";
import { signIn, auth } from "./pocketbase";

export default function Root({ children }) {
  const [userAuth, setUserAuth] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (event) => {
    event.preventDefault();
    setLoading(true)
    await signIn(email,password)
    setLoading(false)
  };

  auth.onChange(async function (user) {
    if (user !== null) {
      setUserAuth(user);
    }
  });

  return (
    <>
      {userAuth != "" ? (
        <>{children}</>
      ) : (
        <div
          style={{
            flexGrow: 1,
            display: "flex",
            justifyItems: "center",
            alignItems: "center",
            marginRight: "auto",
            marginLeft: "auto",
            flexDirection: 'column'
          }}
        >
          <form
            onSubmit={handleSubmit}
            style={{
              display: "flex",
              flexDirection: "column",
              width: "200px",
              margin: "auto",
            }}
          >
            <img src="img/combination-icon.png"  />
            <h1 style={{marginLeft: 'auto', marginRight: 'auto'}}>Docs</h1>
            <label htmlFor="email" style={{ marginBottom: "10px" }}>
              Email:
            </label>
            <input
              type="email"
              id="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              style={{
                marginBottom: "10px",
                padding: "5px",
                borderRadius: "5px",
                border: "1px solid #ccc",
              }}
            />
            <label htmlFor="password" style={{ marginBottom: "10px" }}>
              Password:
            </label>
            <input
              type="password"
              id="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              style={{
                marginBottom: "10px",
                padding: "5px",
                borderRadius: "5px",
                border: "1px solid #ccc",
              }}
            />
            <button
              type="submit"
              style={{
                padding: "5px",
                borderRadius: "5px",
                border: "none",
                backgroundColor: "#fd5367",
                color: "white",
                marginTop: '1rem'
              }}
              disabled={loading}
            >
              {loading ? 'Loading...':'Login'}
            </button>
          </form>
        </div>
      )}
    </>
  );
}

 

 

pocketbase.js 파일은 theme 폴더에 배치합니다.

 

import PocketBase from "pocketbase";

//initialize pocketbase
const app = (() => {
  const POCKETBASE_URL = "https://fastpocket.fly.dev" + "/";
  return new PocketBase(POCKETBASE_URL);
})();

//pass authstore to be used to callback when the user is authenticated
export const auth = app.authStore;

//clears the auth and logs the user out
export const logout = (afterAction = () => {}) => {
  app.authStore.clear();
  afterAction(null);
};

//method to authenticate the user with pocketbase
export const signIn = async (email, password) => {
  try {
    await app.collection("users").authWithPassword(email, password);
  } catch (err) {
    console.error(err);
    alert(err.message);
  }
};

 

 

theme/ColorModeToggle 폴더 속에 index.js 파일을 만들고 아래 소스를 적용합니다.

 

import React from 'react';
import ColorModeToggle from '@theme-original/ColorModeToggle';
import {logout} from '../pocketbase';

export default function ColorModeToggleWrapper(props) {
  return (
    <>
      <ColorModeToggle {...props} />
      <a style={{background: '#fd5469', color: 'white', paddingRight: 10, paddingLeft: 10, paddingBottom: 2, borderRadius: 5, marginLeft: 15, cursor: "pointer"}} onClick={() => logout(() => window.location.reload())}>
        Logout
      </a>
    </>
  );
}

 

 

이렇게 소스를 적용해 놓고, pocketbase를 실행해야 합니다. 

 

포켓베이스 설치도 매뉴얼에 따라 진행합니다.

https://pocketbase.io/docs/

 

PocketBase - Open Source backend in 1 file

Open Source backend in 1 file with realtime database, authentication, file storage and admin dashboard

pocketbase.io

 

 

포켓베이스를 바로 만들면 사용자 컬렉션 이름이 users 입니다. 이것과 pocketbase.js 속의 컬렉션 이름을 맞춰야 합니다. 이것만 잘 맞춰 놓고, 포켓베이스 주소를 소스에 적용하면 잘 동작합니다. 이제 로그인을 해야 확인할 수 있는 비공개 매뉴얼을 만들 수 있게 되었습니다. 

 

출처 : https://www.fastpocket.dev/blogs/how-to-add-authentication-to-docusaurus

 

How To Add Authentication To Docusaurus | FastPocket

Adding authentication to Docusaurus is easy using swizzling

www.fastpocket.dev

 

 

<추가>

로컬에서는 잘 동작하지만 결국 이것을 서버에 올려서 프라이빗하게 구동시켜야 합니다. 2가지 옵션을 사용하면 프론트와 백엔드 모두 무료로 사용할 수 있습니다. 언제까지 무료일지는 모르겠지만, 이 글을 작성하는 시점은 2024-10-11 기준으로는 무료입니다.

 

프론트: https://www.netlify.com/

백엔드: https://pockethost.io/

 

포켓호스트는 신기하게 무료입니다. 무료인 이유가 있을테니 민감한 데이터는 담지 않는 것이 좋겠습니다. 왜 무료인지는 이 링크에 설명해 놓았네요. 간단한 로그인 정도의 사용은 무료일 때 잘 써먹어야 겠습니다.

https://pockethost.io/docs/usage/usage-limits/

 

Usage Limits - PocketHost

PocketHost is an unlimited (fair use) bandwidth, storage, and CPU platform.

pockethost.io