Flaskによるログイン認証
思いのほか、Flaskにおけるログイン認証にはまったので、ここいらでメモ。
ググってみて、ほとんどのログイン機能がうまく表示されず、結局以下のところに落ち着いた。
今回はsqlalchemyを使用しないパターンで実装
まずはインポート
from flask import Flask,render_template,session,request,redirect,url_for
import os
import sqlite3
シークレットキーに乱数を設定
app = Flask(__name__)
app.secret_key = os.urandom(24) #乱数設定
DB = 'user_database.db' #作成したuser_database.dbを変数DBに代入
ログイン用データベース生成(users)
con = sqlite3.connect(DB)
cursor = con.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT NOT NULL,password TEXT NOT NULL)')
con.commit()
con.close()
関数indexにて、サイトトップページアクセス時、ログインセッションがない場合にログイン画面へ遷移するように設定。
@app.route('/')
def index():
if not session.get('login'):
return redirect('login')
else:
return render_template('index.html')
@app.route('/login')
def login():
return render_template('login.html')
ログインチェックのname属性はusernameとpasswordとします。
@app.route('/logincheck', methods=['POST'])
def logincheck():
username = request.form['username']
password = request.form['password']
con = sqlite3.connect(DB)
cursor = con.cursor()
cursor.execute("SELECT * FROM users WHERE username=?", (username,))
user = cursor.fetchone()
con.close()
if user is None:
return redirect(url_for('login')) # ユーザーが存在しない場合はログインページにリダイレクト
# パスワードの検証
if user[2] == password:
session['login'] = True
return redirect(url_for('index')) # 認証成功時にはindexページにリダイレクト
else:
return redirect(url_for('login')) # パスワードが一致しない場合はログインページにリダイレクト
全体的に簡易的なログインにとどめているが、次回はこれを更にパスワードをbcryptなどを使用して、ハッシュ値変換を行うとよいと考える。
全体的な構造は以下のようになるが、logout関数にてセッション削除し、html内に<a href=”/logout”>ログアウト</a>などを付けるなどすればよい。
あとはHTMLを好きなように作るべし。
from flask import Flask,render_template,session,request,redirect,url_for
import os
import sqlite3
app = Flask(__name__)
app.secret_key = os.urandom(24)
DB = 'user_database.db'
con = sqlite3.connect(DB)
cursor = con.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT NOT NULL,password TEXT NOT NULL)')
con.commit()
con.close()
id_pwd = {'seito':'01'}
@app.route('/')
def index():
if not session.get('login'):
return redirect('login')
else:
return render_template('index.html')
@app.route('/login')
def login():
return render_template('login.html')
@app.route('/logout')
def logout():
session.pop('login',None)
return redirect(url_for('index'))
@app.route('/logincheck', methods=['POST'])
def logincheck():
username = request.form['username']
password = request.form['password']
con = sqlite3.connect(DB)
cursor = con.cursor()
cursor.execute("SELECT * FROM users WHERE username=?", (username,))
user = cursor.fetchone()
con.close()
if user is None:
return redirect(url_for('login')) # ユーザーが存在しない場合はログインページにリダイレクト
# パスワードの検証
if user[2] == password:
session['login'] = True
return redirect(url_for('index')) # 認証成功時にはindexページにリダイレクト
else:
return redirect(url_for('login')) # パスワードが一致しない場合はログインページにリダイレクト
@app.route('/insert')
def insert():
return render_template('insert.html')
@app.route('/register', methods=['POST'])
def register():
username = request.form['username']
password = request.form['password']
con = sqlite3.connect(DB)
con.execute('INSERT INTO users (username, password) VALUES(?, ?)',
[username, password])
con.commit()
con.close()
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)