Python+Reflex+Clerkで認証付きWebアプリを簡単に作る
はじめに
ここ最近、PythonのみでUI含めたWebアプリが作成できるライブラリが増えてきています。
それらの中で特にReflexが以下の点で優れてきていると感じており、シンプルなプロダクトであればこれで十分作れるのではないかと思っています。
- 似たようなライブラリであるStreamlitに比べてできることの自由度が高い
- サードパーティによるカスタムコンポーネントが豊富
- ホスティングサービスがあり、簡単にデプロイできる
この記事では、ReflexとClerkというウェブサービスを用いて、Webサービスに不可欠なユーザ認証を含むアプリのデモを作ってみたいと思います。
Clerkとは?
ClerkはWebアプリやモバイルアプリのための認証およびユーザー管理サービスを提供するプラットフォームです。
パスワード認証、SNS認証、ソーシャル認証(Google, Facebook, ...)などに対応しており、Next.jsなどでログインフォームも含めて、アプリに組み込むことができます。
Clerkの設定
まず、Clerkのアカウントを作成し、アプリケーションを新規作成します。
今回は「reflex-clerk-demo」という名前のアプリケーションを作成しました。
ソーシャル認証があると便利なので、「Social Connections」のところから追加したいソーシャル認証を追加します。
FacebookやXなどいろいろありますが、今回はGoogleのみ追加しました。
設定完了したら「API keys」のページに行き、「Publishable key」と「Secret key」が書かれているので、それらをコピーしておきます。
Pythonプロジェクトの作成
Clerkの設定もできたところで、実際のPythonプログラムを作っていきます。
コードの全体は以下にあげています。
実際に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
の修正を最初に提案してくるので、それを修正せずに進めるようにしてください。
今回デプロイしたアプリは以下からアクセスできます。
まとめ
ReflexとClerkを用いて、認証付きのWebアプリのデモを作ってみました。
今回実際にReflexを使ってみて、Reflexを用いれば、Pythonだけである程度のシンプルなアプリケーションが作れそうな感じがします。
他にもいろいろカスタムコンポーネントが用意されていて、チャットアプリやダッシュボードアプリのようなものも比較的簡単に作れそうです。
こういったライブラリがあると、簡易的にプロダクトを作って検証を素早く回せるようになりそうですね!
Discussion