FLASK-LOGINの最低限の使い方と動きについて

# はじめに
[FLASK-ADMIN](https://flask-admin.readthedocs.io/)を使おうとした際にID/パスワードなしに管理画面にいけてしまい、
これは問題だとして認証処理を入れようと思いその方法を調べると[FLASK-LOGIN](https://flask-login.readthedocs.io/)を使うといいよと公式ページにあったので使うことにしました。
しかし、公式ページの導入案内を読んでもどのように動作するのか、何が必要なのかがよくわからず、そもそもFLASK-LOGINは何をしてくれるのかもパっと理解できずキレそうになったのでメモとして書くことにしました。

この記事は最低限の処理と、裏で何やってるんだっていうことをさらっと説明しているものです。
「動作なんてどうでもええねん動けばええんや」って方は「これこのままコピペすればできるんやで」系の記事はいっぱいあるのでそちらを見たほうがいいです。（そういう記事はIMPORT系が薄いのでIMPORTに関してはこの記事をおすすめします）

# そもそも[FLASK-LOGIN](https://flask-login.readthedocs.io/)ってなに？
WEBシステムでよくある認証後の認証情報を保持する方法として遥か大昔からSessionにユーザIDを保持して、
認証が必要なアクセスの度にそのSessionに保持されているIDを使ってユーザ情報を引き出してそれを使うという手法が用いられています。
FLASK-LOGINはそのSession管理とSessionにあるIDを使ってのユーザ情報の取得の簡易化、認証が必要なroute管理をしやすくしてくれるログイン情報管理ライブラリです。
なのでライブラリにLOGINという名前がついてはいますが実際のログイン画面の作成や、ログイン可能かのチェック等は自分自身で作成しないといけないです。
しかも、認証情報の保持がSessionなので今流行のJWT等ではこのライブラリは***対象外***です。
フロントエンドとバックエンドを分けている開発,複数サーバで動かす予定の開発には***不向きなライブラリ***なので注意が必要です。

# 動かすのに必要なもの
* Ptyhon
* Flask
* Flask-Login

# 最低限動かすときに必要なコーディング
## 1.　Flaskクラスインスタンスのsecret_keyを設定
Session情報を暗号化用キーとして必要なsecret_keyを設定しないといけません。
設定しないとエラーとなりキレられます。

```python:secret_key設定サンプル
app = Flask(__name__)
app.secret_key = "好きな文字列(バレると復号化されるので難しいのにしよう！)"
```

## 2.　Flask-LoginのUserMixinを継承した認証情報管理クラスの作成
認証ユーザ情報を保持する用のクラスとその中に必要なプロパティ等が必要なので作成してください。
UserMixinを継承すると最低限必要なプロパティやメソッドを追加してくれますが、***別途 "id"というインスタンス変数又はプロパティが必須なので追加してください。***
これもないと***キレられます***。
また、Sessionで***管理されるのはこのidに登録されている値だけ***です。

```python:認証情報管理クラス（User）サンプル
from flask_login import UserMixin

#　UserMixinを継承したクラスに更にSqlAlchemyのModelを継承させてもOK
class User(UserMixin):
   def __init__(self,id):
　　　　　　　　　　　#　最低限IDがあれば問題ないが普通はユーザ名称などを入れると思われる
      #　詳しくは公式サイトのサンプル参照（https://flask-login.readthedocs.io/）
      self.id = id

```
ちなみにどうしてもUserMixinを継承したくないという場合には必要なプロパティ及びメソッドが公式サイトに記載されているので、そちらを参照の上自力でコーディングすれば動きますが、相当のドMじゃない限りはUserMixinを継承しましょう。

## 3.　Flask-LoginのLoginManagerクラスのインスタンスを作成、APP登録
Flask-Loginの処理をしてもらうためにLoginManagerクラスのインスタンスを作成してAPPを登録します。

```python:LoginManagerクラスインスタンス作成とAPP登録
from flask_login import LoginManager

app = Flask(__name__)
app.secret_key = "好きな文字列(バレると復号化されるので難しいのにしよう！)"

login_manager = LoginManager()
login_manager.init_app(app)
```

## 4.　login_manager.user_loaderデコレータを設定したファンクションを作成
3で作成したLoginManagerインスタンスのuser_loaderデコレータを設定したファンクションを作成してください。
中に各処理はSessionで管理されているIDから認証情報を取る処理です。（DBでもローカルでもなんでもOK） 

```python:login_manager.user_loaderデコレータを設定したファンクションを作成
# 引数user_idにセッション内に登録されているIDが入ります
@login_manager.user_loader
def load_user(user_id):
   #認証情報さえかえせればいいので、別に新規作成しても問題なし
　　　　 return User(user_id)
```
## 5.　Flask-Loginのlogin_userを使用して、認証情報登録処理作成
Flask-Loginのlogin_userをimportして、認証情報を登録する処理を作る。
普通はID/パスワードを入力してもらって入力値チェックをしてそれを登録とするが、別に固定値を設定しても問題なく動作する。

```python:認証情報登録処理作成
from flask_login import login_user
@app.route("/login")
def login():
   login_user(User(1))
　　　　 return "Login完了"
```

## 6.　認証済じゃないと進めれないrouteに対してlogin_reuiredを設定
Flask-Loginのlogin_reuiredをimportして、認証済じゃないと進めれないrouteに対して設定する。
認証情報がない場合401のエラーとなる。
また、デコレータで別途その場合の処理を記述できますが詳しくは公式ページを参照してください。

```python:認証済じゃないと進めれないrouteに対してlogin_reuiredを設定
from flask_login import login_reuired
@app.route("/authorized")
@login_reuired
def authorized():
　　　　 return "認証済なんやで"
```

# おまけ
## 認証済のときの認証情報を取得する処理
Flask-Loginのcurrent_userをimportして使用すれば、@login_manager.user_loaderで返却している値が取得できます。

# 最後
スケールアップやセッション共有なんざアウトオブ眼中なんだという方には、ログイン情報管理系をまとめてくれるのでいいライブラリだと思います。
公式サイトは基本的なことは書いてありますが、import系がサンプルの説明で明確化されてないのでそれがめんどくさいです。
これを見てぜひ楽しいFLASKライフを送っていただければ幸いです。