Streamlitでログインサイトを作成

### 仮想環境作成
```python
python -m venv test
.\test\Scripts\activate
```

### ライブラリインストール
```python
pip install streamlit
```

### 大きな枠を作成
```python 
import streamlit as st

def check_password(stored_password, user_password):
    return stored_password == user_password

def main():
    menu = ["Home", "Login"] 
    choice = st.sidebar.selectbox("Menu", menu)

    if choice == "Home":
        st.subheader("Home")
        # You can display whatever you want on the home page

    elif choice == "Login":
        st.subheader("Login Section")
        username = st.sidebar.text_input("User Name")
        password = st.sidebar.text_input("Password", type='password')
        
        if st.sidebar.checkbox("Login"):
            # You would normally check against secure password hashes in a real application
            stored_password = "streamlit"
            if check_password(stored_password, password):
                st.success("Logged In as {}".format(username))
                task = st.selectbox("Task", ["Add Post", "Analytics", "Profiles"])
                if task == "Add Post":
                    st.subheader("Add Your Post")
                elif task == "Analytics":
                    st.subheader("Analytics")
                elif task == "Profiles":
                    st.subheader("User Profiles")
            else:
                st.warning("Incorrect Username/Password")

if __name__ == "__main__":
    main()
```

### 実行
```
streamlit run main.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2465378/ec61abf9-bda9-9e3f-dd94-d35dad4dab67.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2465378/640e21cd-a90d-236a-4bdb-985cc311db86.png)

### 登録画面を作成
SQLiteを用いて登録画面も作成
```python
import streamlit as st
import sqlite3

def create_users_table():
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute('CREATE TABLE IF NOT EXISTS users(username TEXT, password TEXT)')
    conn.commit()
    conn.close()

def add_user(username, password):
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, password))
    conn.commit()
    conn.close()

def check_user(username, password):
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute('SELECT * FROM users WHERE username = ? AND password = ?', (username, password))
    data = c.fetchall()
    conn.close()
    return len(data) != 0

def main():
    st.sidebar.title("Authentication Demo")
    menu = ["Home", "Login", "SignUp"]
    choice = st.sidebar.radio("Menu", menu)

    if choice == "Home":
        st.subheader("Home")
        # You can display whatever you want on the home page

    elif choice == "Login":
        st.subheader("Login Section")
        username = st.sidebar.text_input("User Name")
        password = st.sidebar.text_input("Password", type='password')

        if st.sidebar.button("Login"):
            if check_user(username, password):
                st.success("Logged In as {}".format(username))
                task = st.selectbox("Task", ["Add Post", "Analytics", "Profiles"])
                if task == "Add Post":
                    st.subheader("Add Your Post")
                elif task == "Analytics":
                    st.subheader("Analytics")
                elif task == "Profiles":
                    st.subheader("User Profiles")
            else:
                st.warning("Incorrect Username/Password")

    elif choice == "SignUp":
        st.subheader("Create New Account")
        new_user = st.text_input("Username")
        new_password = st.text_input("Password", type='password')

        if st.button("Signup"):
            add_user(new_user, new_password)
            st.success("You have successfully created an account.")
            st.info("Go to Login Menu to login")

if __name__ == "__main__":
    create_users_table()
    main()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2465378/5ac95546-2259-ddf9-35c4-e9541b1356f5.png)

### ハッシュ値で保存
先ほどまでのパスワードはハッシュ値で管理していたため、hashlibライブラリを使ってパスワードをSHA256ハッシュとして保存することができます

```python
import streamlit as st
import sqlite3
import hashlib

def hash_password(password):
    return hashlib.sha256(password.encode('utf-8')).hexdigest()

def create_users_table():
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    c.execute('CREATE TABLE IF NOT EXISTS users(username TEXT, password TEXT)')
    conn.commit()
    conn.close()

def add_user(username, password):
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    hashed_password = hash_password(password)
    c.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, hashed_password))
    conn.commit()
    conn.close()

def check_user(username, password):
    conn = sqlite3.connect('users.db')
    c = conn.cursor()
    hashed_password = hash_password(password)
    c.execute('SELECT * FROM users WHERE username = ? AND password = ?', (username, hashed_password))
    data = c.fetchall()
    conn.close()
    return len(data) != 0

def main():
    st.sidebar.title("Authentication Demo")
    menu = ["Home", "Login", "SignUp"]
    choice = st.sidebar.radio("Menu", menu)

    if choice == "Home":
        st.subheader("Home")
        # You can display whatever you want on the home page

    elif choice == "Login":
        st.subheader("Login Section")
        username = st.sidebar.text_input("User Name")
        password = st.sidebar.text_input("Password", type='password')

        if st.sidebar.button("Login"):
            if check_user(username, password):
                st.success("Logged In as {}".format(username))
                task = st.selectbox("Task", ["Add Post", "Analytics", "Profiles"])
                if task == "Add Post":
                    st.subheader("Add Your Post")
                elif task == "Analytics":
                    st.subheader("Analytics")
                elif task == "Profiles":
                    st.subheader("User Profiles")
            else:
                st.warning("Incorrect Username/Password")

    elif choice == "SignUp":
        st.subheader("Create New Account")
        new_user = st.text_input("Username")
        new_password = st.text_input("Password", type='password')

        if st.button("Signup"):
            add_user(new_user, new_password)
            st.success("You have successfully created an account.")
            st.info("Go to Login Menu to login")

if __name__ == "__main__":
    create_users_table()
    main()
```