0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flaskでラズパイの状態を確認するWebアプリを作ってみた(其の四)

Last updated at Posted at 2022-10-09

今回導入した機能

  • テンプレート継承の導入 (其の三で紹介済み)
  • メモリ・CPU・IOの状態を確認できるように free と vmstat コマンドを追加 (其の三で紹介済み)
  • ユーザーログイン認証
  • SQLite3でのユーザーデータ管理

ファイル構成

RaspiApp 
  ├─ static
  |    ├─ css
  |    |   └─ style.css
  |    ├─ db
  |    |   └─ users.sqlite
  |    └─ images
  |        └─ raspi-logo.png
  ├─ templates
  |      ├─ base.html
  |      ├─ get_disk.html
  |      ├─ get_ip_addr.html
  |      ├─ get_mem.html
  |      ├─ get_route.html
  |      ├─ get_socket.html
  |      ├─ get_temp.html
  |      ├─ get_vmstat.html
  |      ├─ index.html
  |      └─ login.html
  └─ raspi_app.py

GitHubリポジトリ

GitHub : CannuWorks/RaspiApp

ユーザーログイン認証

  • Flask-login モジュールを利用しないで実装
  • sessionで管理する

login_auth.png

認証フロー

auth_flow.png

処理プロセス

  1. indexでsession[login] =Trueであるかを確認し、Falseであればloginにリダイレクト
  2. DBに保管されているpasswordは暗号化(ハッシュ化)されているので、入力されたpasswordもget_digest()メソッドで変換して照合する必要がある
  3. idとpasswordを照合し、正しければsession[login] = Tureとして、Boolen値のTrueをセッションにセットする
  4. Trueの場合はindex、Falseの場合はloginにリダイレクトされる
  5. 認証が成功するとindex.html(トップページ/メニューページ)が表示される
  6. 各種コマンドリンクにアクセスすると、sessionsession[login] =Trueであるかを確認し、Trueであればget_xxx()メソッドを実行するが、Falseの場合、loginにリダイレクトされる。

ポイント

  • 2つの条件判断
    • id & passwordでユーザーを照合
    • 照合に成功した場合 session[login] = True をセッションにセットする。以降の処理でそのセッションの状態を常に確認し、認証が成功していないユーザは、エンドポイントに定義したコマンドを実行できない。

コード

app.secret_key = os.urandom(21) 

# Password Digest
def get_digest(password):
    pwd = bytes(password, 'utf-8')
    diget = hashlib.sha256(pwd).hexdigest()
    return diget


# TopPage
@app.route('/')
def index():
    if not session.get('login'):
        return redirect(url_for('login'))
    else:
        return render_template('index.html')


# Login
@app.route('/login')
def login():
    return render_template('login.html')


# lockin check
@app.route('/logincheck', methods=['POST'])
def logincheck():
    user_id = request.form['user_id']
    pwd = request.form['password']
    session['username'] = user_id

    # make pwd hashed by "get_digest()"" function
    password = get_digest(pwd)
    id_pwd_hash = get_user_data()

    if user_id in id_pwd_hash:
        if password == id_pwd_hash[user_id]:
            session['login'] = True
        else:
            session['login'] = False
    else:
        session['login'] = False

    if session['login']:
        return redirect(url_for('index'))
    else:
        return redirect(url_for('login'))


# logout
@app.route('/logout')
def logout():
    session.pop('login', None)
    return redirect(url_for('index'))
login.html
<!-- main block のみ記載 -->
{% block main %}

<h2>Login Authentication</h2>
<h3>Please input User ID and Password!</h3>
<form method="POST" action="/logincheck">
    <p><input placeholder="User ID" type="text" name="user_id"></p>
    <p><input placeholder="Password" type="password" name="password"></p>
    <p><input type="submit" value="SEND"></p>
</form>

{% endblock %}

SQLite3でのユーザーデータ管理

  • データベースを作成 (ファイル名:users.sqlite)
  • テーブルを作成(テーブル名:users)
id name password email
1 use_name user_pwd user@ydomain.com
import sqlite3

# DB connection
def get_user_data():
    sqlite_path = 'static/db/users.sqlite'
    connection = sqlite3.connect(sqlite_path)
    cursor = connection.cursor()
    cursor.execute('SELECT name, password FROM users')
    id_pwd_hash = dict(cursor.fetchall())
    connection.close()
    return id_pwd_hash

ポイント

  1. ファイルの場所を示すパスを作成
  2. connect()メソッドで、データベースに接続
  3. カーソルを取得する
  4. SQL文を実行する
    5. 取得した namepassword を辞書形式で、変数id_pwd_hashにセットする
  5. データベースとのコネクションを切断
  6. id_pwd_hash変数を返す

まとめ

  • 開発環境での実装は一旦終了
  • リファクタリング的活動を実施
    • Flask-loginによる認証
    • BluePrintによる機能分割
    • SqlalchemyでのDB接続
  • nginx + uWSGIによる、Production環境のセットアップ(其の五で紹介)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?