WPGraphQLを認証ユーザーのみ使えるようにする

公開日:2021/12/30更新日:2023/1/21

WordPressでWPGraphQLを使う場合、デフォルトでは誰でもアクセスおよびクエリの実行が可能ですが、WPGraphQL JWT Authenticationのプラグインを同時にインストールすることで、未承認のユーザーにはエラーが返却され、承認済みのユーザーのみデータ取得できるようになります。

インストールと設定

まず、WPGraphQLの設定画面にある、”Limit the execution of GraphQL…”のチェックボタンをオンにし、認証ユーザー以外のクエリ実行を制限します。

次に、WPGraphQL JWT AuthenticationをGitHubからzip形式でダウンロードし、プラグイン画面で手動でアップロードします。

次に、wp-config.php(※他のファイルでも可)に以下のコードを追記します。

define( 'GRAPHQL_JWT_AUTH_SECRET_KEY', 'your-secret-token' );

ここに記述するトークン(※your-secret-tokenの部分)は何でもOKですが、WordPress公式のトークン生成ページがあるので、それを使うのが良いと思います。

ここまでの設定で、承認済みユーザー以外のエンドポイント(/graphql)へのアクセスが弾かれるようになります。

Refresh Tokenの取得

データを取得するために必要なトークンを取得します。

トークンにはauthTokenrefreshTokenの2種類がありますが、authTokenは一定時間が経過すると使えなくなるため、refreshTokenの方を取得します。

WPGraphQLのクエリ実行画面で以下のクエリを実行することでrefreshTokenが返ってくるので、コピーしてください。

mutation LoginUser {
  login(input: {username: "root", password: "root"}) {
    refreshToken
  }
}

usernameとpassword(rootの部分)はWordPressのログインで使っているものです。どちらも適宜変更してください。

データの取得

フロントエンド側の操作に移ります。事前に取得したrefreshTokenをヘッダーにセットすることでデータを取得できます。

以下はNext.jsのgetStaticProps関数を使ったサンプルコードです。この例では、わかりやすいように直接トークンを記述していますが、なるべく環境変数をご活用ください。

const fetchApi = async () => {
  const refreshToken = `eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC90ZXN0LmxvY2FsIiwiaWF0IjoxNjM4OTM4MTA0LCJuYmYiOjE2Mzg5MzgxMDQsImV4cCI6MTY3MDQ3NDEwNCwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSIsInVzZXJfc2VjcmV0IjoiZ3JhcGhxbF9qd3RfNjFhZWUzNzVkZWMxNyJ9fX0.MFcOC5wGxC7BVTghcQWDSH0uDP_9JF4DogZtKR0YKyc`;
  const res = await fetch(`http://test.local/graphql`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${refreshToken}`,
    },
    body: JSON.stringify({
      query: `
      {
        generalSettings {
          email
          url
          title
        }
      }      
      `,
    }),
  });

  const json = await res.json();

  if (json.errors) {
    console.error(json.errors);
    throw new Error("Failed to fetch API");
  }

  return json.data;
};

export const getStaticProps = async () => {
  const data = await fetchApi();

  return {
    props: { data },
  };

  // dataの中身は以下の通り
  // {
  //   generalSettings: {
  //     email: '[email protected]',
  //     url: 'http://your-site.com',
  //     title: 'Test Site'
  //   }
  // }
};