Streamlit v1.46.1で簡易的なログイン機能を実装
HTML、CSS、JavaScriptを使わなくてもPythonさえ知っていればお手軽なWebアプリが作れ、データ分析やデータの可視化などに便利なStreamlitに触れてみました。Streamlitは2019 年に正式リリースされ、2025/07現在の最新バージョンはv1.46.1の比較的新しいフレームワークです。
※初めての方はこちらの「streamlitを使ったお手軽Webアプリ開発」も参考になると思います。
目次
Streamlitは用意されているウィジェットを組み合わせてWebアプリを構築していきますが、上から順番に処理していき、Reloadすれば全て初期化されて入力した値が消えます。永続化するにはどうすれば良いのか、ページ遷移はどうするのかなど、ユーザー認証の実装から考察してみましたので、忘れないようにメモしておきます。
開発環境
- OS:Ubuntu22.04 or Debian Linux12
- Streamlit:v1.46.1
Streamlitの基本的な使い方
Pythonの仮想環境からStreamlitをインストールする。
Streamlitをインストール
pip install streamlit
ユーザー情報の準備
基本動作確認のため、ユーザーの情報はusernameとpasswordのみとしています。パスワードもここでは平文で済ませていますが、本来はハッシュ化します。
# ユーザー情報
dict_data = [
{"username": "sanji", "password": "pass123"},
{"username": "usop", "password": "pass345"},
]
画面構成
色々試してみて一番しっくりきたのは、ログインフォームを左側に配置し、メイン画面を右側にくるようにすることでした。左側に寄せるにはウィジェットのsidebarを使います。st.sidebarにはウィジェットを置くことができますので、ここにログインフォームを作成します。便利なことに、不要なときは画面から隠すこともできます。
画面構成

画面の遷移
URLによるページ遷移は基本的に使いません。代わりにif文の分岐処理で切り替えます。ここでは簡単なst.session_stateを使った状態管理にて画面遷移させます。
①遷移先を定義します。
# 画面遷移先
def Home():
st.header('ホーム画面')
# 何らかの処理を書く
def info():
st.header('お知らせ')
# 何らかの処理を書く
def inquiry():
st.header('お問い合わせ')
# 何らかの処理を書く
②セッション変数の初期化
# 状態管理
if "page" not in st.session_state:
st.session_state["page"] = "login" # ← 認証用のセッション
if "mypage" not in st.session_state:
st.session_state["mypage"] = "Home" # ← ログイン後の画面遷移用のセッション
③画面遷移
# 画面遷移
if st.session_state["mypage"] == "Home":
Home()
elif st.session_state["mypage"] == "お知らせ":
info()
elif st.session_state["mypage"] == "お問い合わせ":
inquiry()
実装結果
ログイン機能については、今はリストでユーザー管理しているだけなので、for文で繰り返し処理して、usernameとpasswordが一致しているユーザーを探しています。
プロジェクト内にapp.pyファイルを作成し、今までのコードを実装して動作確認します。
app.py
import streamlit as st # v1.46.1
# ↓画像を扱いたい方は以下もimportすると便利です。
from PIL import Image
# ユーザー情報
dict_data = [
{"username": "sanji", "password": "pass123"},
{"username": "usop", "password": "pass345"},
]
# 状態管理
if "page" not in st.session_state:
st.session_state["page"] = "login"
if "mypage" not in st.session_state:
st.session_state["mypage"] = "Home"
# 画面遷移先
def Home():
st.header('ホーム画面')
# 何も無いと寂しいので、取り敢えず画像を左右に並べています。
img1="./images/公園の河.jpg" # ←プロジェクト内で保存
img2="./images/palazzina寺院.jpg" # ←プロジェクト内で保存
# ここで画面を左右に2分割しています。
col1,col2 = st.columns(2)
# 左側に画像を表示
with col1:
image1= Image.open(img1)
st.image(image1)
# 右側に別の画像を表示
with col2:
image2 = Image.open(img2)
st.image(image2)
def info():
st.header('お知らせ')
# 何らかの処理を書く
def inquiry():
st.header('お問い合わせ')
# 何らかの処理を書く
# 再度バーの実装
with st.sidebar:
if st.session_state["page"]== "login":
st.header('ログイン')
username = st.text_input("ユーザー名")
password = st.text_input("パスワード", type="password")
if st.button("ログイン"):
for user in dict_data:
if user.get("username") == username and user.get("password") == password:
st.session_state["page"] = "dashboard"
st.session_state["mypage"] = 'Home'
# ↓Streamlitのv1.26.0以降でst.experimental_rerun()はst.rerun()に置き換えられました。
st.rerun()
break
st.markdown("<span style='color:red;'>ログイン失敗</span>", unsafe_allow_html=True)
elif st.session_state["page"]== "dashboard":
st.markdown("ログインに成功しました。 \nようこそ!!") # ← 半角スペース2個+\nで改行になる
dash_page = st.selectbox('選択してください',['Home','お知らせ', 'お問い合わせ'])
st.session_state["mypage"] = dash_page
# メイン画面の設計
if st.session_state["page"] == "dashboard":
# st.header('ダッシュボード')
# 画面遷移
if st.session_state["mypage"] == "Home":
Home()
elif st.session_state["mypage"] == "お知らせ":
info()
elif st.session_state["mypage"] == "お問い合わせ":
inquiry()
# ログアウトボタン
if st.button('logout'):
st.session_state["page"] = 'login'
st.rerun() # 再読込
動作確認
以下のコマンドを打ってブラウザ上で動作確認します。
streamlit run app.py
# 以下はメッセージ
You can now view your Streamlit app in your browser.
Local URL: http://localhost:8501
Network URL: http://192.168.2.117:8501
localhost:8501
以上です。😀