前書き
前回に続き、USER認証でデータベースを生成するAPI処理を書いています。
ログイン認証はFASTAPI側で完成している前提です。
Streamlitの認証
一般的なStreamlitの認証は以下です。
今回はStreamlit側も完成しており、インデントを一切触りたくないので、メインストリームで何とかします。
クソ認証
検討時間は、実質半日です。
今回はSTREAMLITのエンドポイントにパスパラメータを書き加えるという、
斬新な認証を付与することとしました。
FASTAPI側
BACKENDからリダイレクトされるURLは以下
http://host:8501/?user=moto&auth=True
# StreamlitのURLとクエリパラメーターを定義する
next_url = 'http://host:8501/' #streamlit-app のURL
query_params = {'user': username,'auth':True}
return_url = f'{next_url}?{urllib.parse.urlencode(query_params)}'
Streamlit側
・URLのパスパラメータから、userと認証完了をGET
・AUTHがFalseなら、ログイン画面のURLを示して停止(なんと斬新な)
・あとはsession_stateのユーザー名でチョメチョメ
from streamlit import session_state as ses # streamlitからsession_stateをsesという名前でインポート
# セッション情報を取得する関数
params = st.experimental_get_query_params()
username = params.get("user",[""])[0]
auth = params.get("auth",[""])[0]
if auth:
ses.user = username
else:
stc.html(f"<a href={login_url} target='_blank'>Click here to Login</a>")
st.stop()
詳細
このコードは、Streamlitの実験的な機能であるst.experimental_get_query_params()
を使用して、現在のセッションのクエリパラメータを取得し、それらの値をparams
変数に格納します。これは、URLの末尾に付けられた任意のクエリパラメータ(例えば ?user=john&auth=1234
)を扱うことができます。
その後、params.get()
関数を使用して、特定のクエリパラメータ(この場合は"user"と"auth")の値を取得します。
以下に各行の詳細な説明を提供します:
# セッション情報を取得する関数
params = st.experimental_get_query_params()
この行では、st.experimental_get_query_params()
関数を使用して現在のセッションのクエリパラメータを取得し、それらの値をparams
変数に格納します。
username = params.get("user",[""])[0]
この行では、params.get()
関数を使用して"user"という名前のクエリパラメータを探し、その値をusername
変数に格納します。もし"user"パラメータが存在しない場合、デフォルト値として空文字列("")が返されます。
auth = params.get("auth",[""])[0]
これも同様に、"auth"という名前のクエリパラメータを探し、その値をauth
変数に格納します。もし"auth"パラメータが存在しない場合、デフォルト値として空文字列("")が返されます。
これらのパラメータは、一般的にユーザー認証やセッション管理に使用されます。
まとめ
- もちろんURLのルールが他人にバレるとNGです。
- 社内アプリなので、まったく問題ありません
- 凝ったStreamlitの認証など、最初から挑んではいけません → これ大事!
最後に
- authをtokenに変えて、ユーザー名を暗号化するのも良いかもしれません