[블로그 구현 with Flask] 2. flask_login 라이브러리 기능
flask_login 라이브러리
사용자를 로그인 시, flask_login 라이브러리를 이용하면, 사용자 관련 session 정보를 HTTP response에 넣어 보내주고 이를 기반으로 flask 서버에서 사용자를 구별할 수 있는 기능 제공
1. 사용자가 로그인하면, 로그인 정보를 User class에서 객체로 가져오고, LoginManager()에 추가하여 세션 생성
- flask 서버가 리턴 시 해당 세션 정보를 웹페이지에 송부
2. current_user 객체에 해당 객체가 저장
- current_user.id : 사용자 ID
- current_user.is_authenticated : 사용자가 로그인되었는지를 나타내는 값 (Boolean)
3. 로그인 후 웹페이지로 flask 서버 접근 시 전달받은 세션 정보를 기반으로 접근
- 세션 정보에서 id를 추출해서 LoginManager()에서 다루는 id일 경우, @login_required로 데코레이터가 추가된 API 접근 허용
4. 사용자가 로그아웃 시 LoginManager()에서 해당 id 제거
flask_login 초기 설정
# session 생성을 위해 secret key 정의
app.secret_key = 'secret_key' # os.urandom(24)
# strong 옵션 사용 시 session 보안 적용
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.session_protection = 'strong'
사용자 session 생성
User 클래스 기반으로 사용자 객체를 생성한 후, flask_login.login_user() 함수에 해당 객체를 넣어주면 해당 사용자 기반 session 생성
해당 session은 HTTP response에 넣어져서 사용자 웹브라우저에 송부됨
- HTTP Response의 Set-Cookie 옵션에 해당 session 정보를 넣어서 송부
- 사용자 웹브라우저에서는 추후 해당 서버 주소로 HTTP request 송부 시 해당 session 정보를 자동으로 넣어서 요청
- flask_login은 HTTP request에서 자동으로 session 정보를 가져와서 사용자 구분
session 생성 시, 사용자 HTTP request에 들어 있는 사용자 IP address와 user agent 등을 함께 참조해서 session을 생성
from flask_login import login_user
user = User.create(user_email, blog_id)
login_user(user)
login_manager 관련 사전 선언 함수
로그인 후 최초 current_user 호출 시 다음 코드 호출
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
@login_required 데코레이터로 로그인 후 접근 가능한 페이지 protection 기능
로그인이 안된 채로 해당 페이지 접근 시 @login_manager.unauthorized_handler에 정의된 함수를 호출
@login_manager.unauthorized_handler
def unauthorized():
return make_response(jsonify(success=False), 401)
User class 구현
User class는 User Mixin class 상속해야 함
속성으로 사용자를 구분할 수 있는 id를 반드시 갖고 있어야 함
class User(UserMixin):
def __init__(self, user_id, user_email, blog_id):
self.id = user_id
self.user_email = user_email
self.blog_id = blog_id
def get_id(self):
return str(self.id)
@staticmethod
def get(user_id):
mysql_db = conn_mysqldb()
db_cursor = mysql_db.cursor()
sql = "SELECT * FROM user_info WHERE USER_ID = '" + str(user_id) + "'"
db_cursor.execute(sql)
user = db_cursor.fetchone()
if not user:
db_cursor.close()
return None
print(user)
user = User(user_id=user[0], user_email=user[1], blog_id=user[2])
db_curosr.close()
return user
@staticmethod
def find(user_email):
mysql_db = conn_mysqldb()
db_cursor = mysql_db.cursor()
sql = "SELECT * FROM user_info WHERE USER_EMAIL = '" + str(user_email) + "'"
db_cursor.execute(sql)
user = db_cursor.fetchone()
if not user:
db_cursor.close()
return None
print(user)
user = User(user_id=user[0], user_email=user[1], blog_id=user[2])
db_cursor.close()
return user
@staticmethod
def create(user_email, blog_id):
user = User.find(user_email)
if user == None:
mysql_db = conn_mysqldb()
db_cursor = mysql_db.cursor()
sql = "INSERT INTO user_info (USER_EMAIL, BLOG_ID) VALUES ('%s', '%s')" % (str(user_email), str(blog_id))
db_cursor.execute(sql)
mysql_db.commit()
return User.find(user_email)
else:
return user