간단하게 "flask 에서 로그인 기능을 도와주는 라이브러리 flask_login 이 있다"
, "flask_login 라이브러리를 이용하면 사용자 정보를 세션에 저장한다."
정도만 알고있었다. 실제로 구현해보려니 주로 사용한다는 라이브러리치고는 한글로 된 자료가 적어서 정리해보았다.
- flask_login version : 0.5.0
- 현재 개발중인 WE 프로젝트 소스코드 사용
pip install flask-login
Flask 프레임워크로 개발한 웹 어플리케이션의 로그인 기능을 쉽게 구현할 수 있도록 도와주는 라이브러리이다. 필수로 사용해야 하는 것은 아니며 사용자 정보 세션 관리를 쉽게 도와주는 용도로 사용한다.
flask_login에서 사용할 클래스 객체를 생성한다. 일반 모델 객체 생성하듯이 똑같이 생성한다. 사용자 정보에 저장하고 싶은 값을 기준으로 만든다. 나는 user_id만 필요하기 때문에 user_id만 포함하였다.
app/model/common/model_user.py
# flask_login에서 제공하는 사용자 클래스 객체
from flask_login import UserMixin
# DB 연결 정보가 저장되어 있는 config
from app.config import DB
# 쿼리문 실행 함수
from app.model.common.model_db_connect import select, insert, update, delete
# UserMixin 상속하여 flask_login에서 제공하는 기본 함수들 사용
class User(UserMixin):
# User 객체에 저장할 사용자 정보
# 그 외의 정보가 필요할 경우 추가한다. (ex. email 등)
def __init__(self, user_id):
self.user_id = user_id
def get_id(self):
return str(self.user_id)
# User객체를 생성하지 않아도 사용할 수 있도록 staticmethod로 설정
# 사용자가 작성한 계정 정보가 맞는지 확인하거나
# flask_login의 user_loader에서 사용자 정보를 조회할 때 사용한다.
@staticmethod
def get_user_info(user_id, user_pw=None):
result = dict()
try:
sql = ""
sql += f"SELECT USER_ID, USER_NAME, `PASSWORD`, COMPANY_CODE, DEPARTMENT_CODE, POSITION_CODE, AUTH_CODE, "
sql += f"REGISTER_DATETIME, LOGIN_DATETIME, LASTWEEK_REPORT_ID, THISWEEK_REPORT_ID, "
sql += f"INSERT_USER_ID, INSERT_DATETIME, UPDATE_USER_ID, UPDATE_DATETIME "
sql += f"FROM tn_user_info "
if user_pw:
sql += f"WHERE USER_ID = '{user_id}' AND `PASSWORD` = '{user_pw}'; "
else:
sql += f"WHERE USER_ID = '{user_id}'; "
result = select(sql)
except ex:
result['result'] = 'fail'
result['data'] = ex
finally:
return result
flask_login 라이브러리의 로그인 관련 기능을 담고 있는 로그인 객체이다. Flask 객체로 생성한 어플리케이션(ex.app) 을 연결한다.
app/init.py
from flask import Flask
from flask_login import LoginManager
app = Flask(__name__) # flask 객체 생성
login_manager = LoginManager()
login_manager.init_app(app) # app 에 login_manager 연결
요청 전 로그인된 사용자인지 판단하는 기능을 실행하기 전 사용자 정보를 조회해오는 user_loader
와 로그인된 사용자가 아닐 경우의 처리를 관리하는 unauthorized_handler
를 주로 사용한다.
app/init.py
# flask_login에서 제공하는 login_required를 실행하기 전 사용자 정보를 조회한다.
@login_manager.user_loader
def user_loader(user_id):
# 사용자 정보 조회
user_info = User.get_user_info(user_id)
# user_loader함수 반환값은 사용자 '객체'여야 한다.
# 결과값이 dict이므로 객체를 새로 생성한다.
login_info = User(user_id=user_info['data'][0]['USER_ID'])
return login_info
# login_required로 요청된 기능에서 현재 사용자가 로그인되어 있지 않은 경우
# unauthorized 함수를 실행한다.
@login_manager.unauthorized_handler
def unauthorized():
# 로그인되어 있지 않은 사용자일 경우 첫화면으로 이동
return redirect("/")
login_manager의 기능은 말그대로 도와주는 역할이다. 실제로 세션에 저장 및 삭제의 기능을 하지는 않는다. 세션에 정보를 관리하기 위해 flask_login의 login_user
와 logout_user
함수를 사용한다. login_user는 사용자 정보를 session에 저장하고 logout_user는 session 정보를 삭제한다.
app/view/default/common/login.py
from flask import render_template, redirect, request, url_for
from app import app
from flask_login import login_user, logout_user
from app.model.common.model_menu import Menu
from app.model.common.model_user import User
@app.route('/')
def root():
return redirect('/login')
@app.route('/login')
def login():
return render_template('common/template_login.html')
# 로그인 실행
# 로그인 계정 정보는 post로 받아오지만
# 일반 리소스들은 get으로 받아오므로 get과 post모두 선언해줘야 한다.
@app.route('/login/get_info', methods=['GET', 'POST'])
def login_get_info():
user_id = request.form.get('userID')
user_pw = request.form.get('userPW')
if user_id is None or user_pw is None:
return redirect('/relogin')
# 사용자가 입력한 정보가 회원가입된 사용자인지 확인
user_info = User.get_user_info(user_id, user_pw)
if user_info['result'] != 'fail' and user_info['count'] != 0:
# 사용자 객체 생성
login_info = User(user_id=user_info['data'][0]['USER_ID'])
# 사용자 객체를 session에 저장
login_user(login_info)
return redirect('/main')
else:
return redirect('/relogin')
# 로그인 실패 시 재로그인
@app.route('/relogin')
def relogin():
login_result_text = "로그인에 실패했습니다. 다시 시도해주세요."
return render_template('common/template_login.html', login_result_text=login_result_text)
# 로그아웃
@app.route('/logout')
def logout():
# session 정보를 삭제한다.
logout_user()
return redirect('/')
flask_login에서 제공하는 login_required를 이용하여 특정 요청을 실행하기 전 로그인이 필요한 기능에서 요청을 한 사용자가 로그인된 사용자인지 확인한다. 해당 사용자 정보는 user_loader를 이용한다. 로그인된 사용자가 아닐 경우 unauthorized가 실행된다.
app/view/default/common/main.py
from flask import render_template, redirect
from app import app
from flask_login import login_required
from app.model.common.model_menu import Menu
@app.route("/main")
# 로그인이 필요한 기능에 선언
@login_required
def main():
menu_list = Menu().get_menu_list()
if menu_list['result'] == 'fail':
menu_list = None
else:
menu_list = menu_list['data']
return render_template("common/layout/layout_basic.html",
menu_list=menu_list)
이후에 추가되는 기능에서 login_required 데코레이터만 추가하면 로그인한 사용자인지 쉽게 판단할 수 있다.
login_required는 해당 경로의 코드를 실행하기 전 로그인된 사용자인지 판단하여 로그인된 사용자만 기능을 실행할 수 있도록 한다. is_authenticated는 직접 로그인된 사용자인지 판단하여 특정 로직을 구현할 수 있다.
app/view/default/common/login.py
@app.route('/')
def root():
if current_user.is_authenticated:
return redirect('/main')
else:
return redirect('/login')
기본 경로로 접속 시 로그인된 사용자는 메인화면으로 로그인하지 않은 사용자는 로그인화면으로 이동
Flask-Login 0.4.1 공식문서
Flask-Login 0.5.0 깃허브
20210918 is_authenticated 관련 추가
Greetings! Very helpful advice within this article! It is the little changes that produce the largest changes. Many thanks for sharing!
https://infocampus.co.in/ui-development-training-in-bangalore.html
https://infocampus.co.in/web-development-training-in-bangalore.html
https://infocampus.co.in/mern-stack-training-in-bangalore.html
https://infocampus.co.in/reactjs-training-in-marathahalli-bangalore.html
https://infocampus.co.in/javascript-jquery-training-in-bangalore.html
https://infocampus.co.in/data-structure-algorithms-training-in-bangalore.html
https://infocampus.co.in/angularjs-training-in-bangalore.html
https://infocampus.co.in/
https://infocampus.co.in/full-stack-development-training-in-marathahalli.html
https://infocampus.co.in/mean-stack-development-training-in-banglore.html
https://infocampus.co.in/web-designing-training-in-bangalore.html
https://infocampus.co.in/front-end-development-course-in-bangalore.html