🧑💻
react-query-authでユーザ認証フロントエンドを実装する
react-query-authとは
- https://github.com/alan2207/react-query-auth
- React Queryを拡張して、ユーザ認証フロントエンドの実装に役立つ機能を提供します。
React Queryとは
- https://react-query.tanstack.com/
- サーバに保存されている情報をReactで状態管理するのに役立つライブラリ
- APIのrefetchやレスポンスのキャッシュをいい感じにやってくれます。
react-query-authは何をするのか
- プロバイダとフックを提供します。これにより、ログインユーザの情報や、認証メソッド(login, logout, signup)を任意のコンポーネントから利用できるようになります。
- 認証メソッドのインターフェースを提供します。その通りに実装することで、認証フロントエンドを設計したことがない人にでもそれっぽく実装できます(参考実装として利用できます)
- 内部でReact Queryを利用しているので、キャッシュや、リアルタイムのログイン判定をよしなにやってくれます。
- 実際に動作させてみたところ、ローカルストレージのトークンを削除したり、APIと疎通できないようにすると、ログイン状態が解除されるようでした。
react-query-authは何をしないのか
- 認証メソッドの実装は提供しません(インターフェースのみ)。よって、任意の認証APIを利用できます。
- 認証情報の保存については何も提供しません。よって、トークンの種類(session / JWT)や保存場所(Cookie / local storage)を選びません。
react-query-authが向いているユースケース
- 認証フロントエンドを自前で実装する場合
- 認証バックエンドにロックインされないので、入替がありうる場合も対応できます。
- 認証フロントエンドの実装に慣れていない方は、本ライブラリをリファレンス実装として使うことができそうです。
- 逆に、Firebase Authenticationなど、React SDKが提供されている認証プロバイダを使う場合は敢えて採用する必要は無さそうです。
サンプル実装
-
公式
- ログイン・ログアウトに合わせて認証情報をローカルストレージに読み書き破棄する実装になっているので、実際の実装の参考にできそうです。
-
bulletproof-react
- Reactのリファレンス実装である bulletproof-react でも採用されていたりします。
- 参考記事: Reactベストプラクティスの宝庫!「bulletproof-react」が勉強になりすぎる件
react-query-authの使い方
プロバイダ, フックの初期化
export const { AuthProvider, useAuth } = initReactQueryAuth<User, Error>({
loadUser,
loginFn,
registerFn,
logoutFn,
});
initReactQueryAuth
で初期化します。その際に以下のパラメータを渡します。
- interface(
User
,Error
)- 認証を通してやりとりされるオブジェクトの型定義を渡します。
- 例えば,
User
のインスタンスにはログインユーザの状態が格納されます。
- 関数(
loadUser
,loginFn
, etc.)- ログイン・ログアウトなどの関数の実装を渡します。
- 関数はインターフェースが決まっています。例えば,
loginFn
は(data:any) => Promise<User>
となります。
プロバイダの利用
export const App = () => {
return (
<QueryClientProvider client={queryClient}>
<AuthProvider>
{//the rest of the app}
</AuthProvider>
</QueryClientProvider>
);
};
-
initReactQueryAuth
で初期化したAuthProvider
をアプリにラップします。 - 加えて、React Queryのプロバイダ
QueryClientProvider
もラップする必要があります。
フックの利用
export const UserInfo = () => {
const { user, login, logout, register, error, refetch } = useAuth();
return <div>My Name is {user.name}</div>;
};
-
initReactQueryAuth
で初期化したuseAuth
をアプリで利用します。 -
user
はinitReactQueryAuth
に渡したloadUser
からUser
型のオブジェクトです。 -
login
はinitReactQueryAuth
に渡したloginFn
関数です。
Discussion