😎

Python+Reflex+Clerkで認証付きWebアプリを簡単に作る

2024/06/21に公開

はじめに

ここ最近、PythonのみでUI含めたWebアプリが作成できるライブラリが増えてきています。

https://zenn.dev/neka_nat/articles/f2f5b6ebeb049a

それらの中で特にReflexが以下の点で優れてきていると感じており、シンプルなプロダクトであればこれで十分作れるのではないかと思っています。

この記事では、ReflexとClerkというウェブサービスを用いて、Webサービスに不可欠なユーザ認証を含むアプリのデモを作ってみたいと思います。

Clerkとは?

ClerkはWebアプリやモバイルアプリのための認証およびユーザー管理サービスを提供するプラットフォームです。
パスワード認証、SNS認証、ソーシャル認証(Google, Facebook, ...)などに対応しており、Next.jsなどでログインフォームも含めて、アプリに組み込むことができます。

https://clerk.com/

Clerkの設定

まず、Clerkのアカウントを作成し、アプリケーションを新規作成します。
今回は「reflex-clerk-demo」という名前のアプリケーションを作成しました。
ソーシャル認証があると便利なので、「Social Connections」のところから追加したいソーシャル認証を追加します。
FacebookやXなどいろいろありますが、今回はGoogleのみ追加しました。

設定完了したら「API keys」のページに行き、「Publishable key」と「Secret key」が書かれているので、それらをコピーしておきます。

Pythonプロジェクトの作成

Clerkの設定もできたところで、実際のPythonプログラムを作っていきます。
コードの全体は以下にあげています。

https://github.com/neka-nat/reflex-clerk-demo

実際に0からプロジェクトを作る際は、reflexがプロジェクト作成用のコマンドを用意しているのでそれを用います。

reflex init

以下のような形で、初期のテンプレートがいくつか用意されていて、どれを使うか聞かれます。
今回は0番のblankにしました。

使用するPythonパッケージはreflexとreflex-clerkになります。
pipyから両方ともインストールできるのですが、reflex-clerkはpypiのものがうまく動作しなかったのでこちらはgithubから直接インストールしました。

pip install reflex
pip install git+https://github.com/kroo/reflex-clerk.git

次にメインとなるコードです。
ページの構成としては、最初のページにログインページがあり、ログインすると/test-authページに遷移します。
/test-authページにはログアウトボタンがあり、ログアウトすると最初のページに戻ります。

import reflex as rx

import reflex_clerk as clerk
import reflex_clerk.clerk_client
from dotenv import load_dotenv

load_dotenv()

class State(rx.State):
    """The app state."""
    ...


@rx.page("/")
def index() -> rx.Component:
    return (
        clerk.clerk_provider(
            rx.center(
                rx.vstack(
                    rx.heading("Reflex Clerk Demo!", size="9"),
                    clerk.signed_out(
                        rx.button(
                            clerk.sign_in_button(force_redirect_url="/test-auth"),
                            size="4",
                            color_scheme="gray",
                            background="black"
                        ),
                    ),
                    clerk.signed_in(
                        rx.button(
                            "test-auth",
                            on_click=rx.redirect("/test-auth"),
                        )
                    ),
                    align="center",
                    spacing="7",
                ),
                height="100vh",
            ),
        )
    )


@rx.page("/test-auth")
def auth_required_page():
    return clerk.clerk_provider(
        rx.center(
            rx.vstack(
                rx.heading("Auth required test"),
                clerk.signed_in(
                    rx.cond(
                        clerk.ClerkState.user.has_image,
                        rx.chakra.avatar(
                            src=clerk.ClerkState.user.image_url,
                            name=clerk.ClerkState.user.first_name,
                            size="xl",
                        ),
                    )
                ),
                clerk.protect(
                    rx.fragment("You are logged in as ", clerk.ClerkState.user.first_name),
                    fallback=clerk.redirect_to_sign_in()
                ),
                clerk.signed_in(
                    rx.button(
                        clerk.sign_out_button(),
                        size="4",
                        color_scheme="gray",
                        background="black"
                    )
                ),
            ),
       ),
    )


app = rx.App()
reflex_clerk.install_signin_page(app)

以下のコマンドでアプリを立ち上げ、ブラウザでlocalhost:3000にアクセスしてみます。

reflex run

最初のページ

ログイン画面

ログイン後

デプロイ

デプロイにはrequirements.txtを使用するので、以下のような設定で保存しておきます。

reflex==0.5.4
authlib==1.3.1
python-dotenv==1.0.1
reflex-clerk @ git+https://github.com/kroo/reflex-clerk@master

ホスティングサービスにデプロイしてみます。

reflex login
reflex deploy

reflex deployでいろいろ聞かれるので、それらに答えていきます。環境変数の設定などもここで行います。
注意点としてはreflexがrequirements.txtの修正を最初に提案してくるので、それを修正せずに進めるようにしてください。

今回デプロイしたアプリは以下からアクセスできます。

https://reflex-clerk-demo.reflex.run/

まとめ

ReflexとClerkを用いて、認証付きのWebアプリのデモを作ってみました。
今回実際にReflexを使ってみて、Reflexを用いれば、Pythonだけである程度のシンプルなアプリケーションが作れそうな感じがします。
他にもいろいろカスタムコンポーネントが用意されていて、チャットアプリやダッシュボードアプリのようなものも比較的簡単に作れそうです。
こういったライブラリがあると、簡易的にプロダクトを作って検証を素早く回せるようになりそうですね!

Discussion