Flask

Chapter 4-7(1) 로그인, 세션 관리 및 보안 페이지 Authentication/ Session

Chansman 2025. 4. 22. 20:23

Flask 애플리케이션 설명: 로그인, 세션 관리 및 보안 페이지

이번 애플리케이션에서는 사용자가 로그인하여 비밀번호 확인세션 관리를 통해 보호된 비밀 페이지에 접근할 수 있는 구조입니다. 사용자는 로그인 정보를 제출하면 세션에 username을 저장하고, 이를 통해 로그인 상태를 유지합니다. 세션이 만료되거나 로그아웃을 하면 비밀 페이지에 접근할 수 없게 됩니다.


1. app.py - Flask 애플리케이션

from flask import Flask, render_template, request, redirect, session, flash
from datetime import timedelta

app = Flask(__name__)

app.secret_key = 'flask-secret-key'  # 실제 배포시에는 .env나 yaml 파일에 저장
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)  # 세션 만료 기간 설정

# admin user (간단한 딕셔너리로 사용자 정보 저장)
usrs = {
    'john': 'pw123',
    'leo': 'qw123'
}

# 로그인 화면
@app.route('/')
def index():
    return render_template('login.html')

# 로그인 처리
@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']

    # 사용자 확인
    if username in usrs and usrs[username] == password:
        session['username'] = username  # 세션에 사용자 이름 저장
        session.permanent = True  # 세션을 영구적으로 유지

        return redirect('/secret')  # 로그인 성공 시 비밀 페이지로 리디렉션
    else:
        flash('Invalid username or password')  # 로그인 실패 시 플래시 메시지
        return redirect('/')  # 로그인 화면으로 리디렉션

# 비밀 페이지 (세션 확인)
@app.route('/secret')
def secret():
    if 'username' in session:  # 세션에 username이 존재하면 비밀 페이지에 접근 가능
        return render_template('secret.html')
    else:
        return redirect('/')  # 로그인되지 않은 사용자는 로그인 화면으로 리디렉션

# 로그아웃 처리
@app.route('/logout')
def logout():
    session.pop('username', None)  # 세션에서 username 제거
    session.clear()  # 세션 클리어
    return redirect('/')  # 로그인 화면으로 리디렉션

if __name__ == '__main__':
    app.run(debug=True)

주요 부분 설명

  1. Flask 앱 설정:
    • app.secret_key: 세션을 사용할 때 필요한 비밀 키입니다. 실제 배포 시 .env 파일에 저장해야 합니다.
    • app.config['PERMANENT_SESSION_LIFETIME']: 세션이 얼마나 오래 유지될지를 설정하는 옵션입니다. 이 예시에서는 7일로 설정했습니다.
  2. usrs:
    • 이 딕셔너리에는 간단한 사용자 데이터 (username과 password)를 저장하고 있습니다. 실제 환경에서는 데이터베이스나 다른 안전한 방법으로 저장하는 것이 좋습니다.
  3. 로그인 (/login):
    • 사용자가 로그인 폼을 제출하면 POST 요청이 /login으로 보내지고, 서버는 해당 정보를 usrs 딕셔너리와 비교하여 유효성 검사를 합니다.
    • 로그인 성공 시 세션에 사용자 이름을 저장하고, session.permanent = True를 설정하여 세션을 영구적으로 유지합니다.
    • 로그인 실패 시 flash 메시지를 표시하고 다시 로그인 페이지로 리디렉션합니다.
  4. 비밀 페이지 (/secret):
    • 세션에 username이 존재하면 비밀 페이지에 접근할 수 있습니다.
    • 세션에 username이 없으면 로그인 페이지로 리디렉션됩니다.
  5. 로그아웃 (/logout):
    • session.pop('username', None)을 사용하여 세션에서 username을 제거하고, session.clear()로 세션을 완전히 비웁니다.
    • 로그아웃 후 로그인 페이지로 리디렉션됩니다.

2. login.html - 로그인 페이지 템플릿

<!DOCTYPE html>
<html>
  <head>
    <title>Login</title>
  </head>
  <body>
    <h2>Login</h2>
    <form method="POST" action="/login">
      <input type="text" name="username" placeholder="Username" required>
      <input type="password" name="password" placeholder="Password" required>
      <button type="submit">Login</button>
    </form>
  </body>
</html>
  • 로그인 폼: 사용자는 username과 password를 입력하고 제출할 수 있습니다. 폼은 POST 방식으로 /login URL로 데이터를 보냅니다.
  • 필수 입력: required 속성을 사용하여 사용자가 반드시 값을 입력하도록 합니다.

3. secret.html - 비밀 페이지 템플릿

<!DOCTYPE html>
<html>
  <head>
    <title>Secret Page</title>
  </head>
  <body>
    <h2>Welcome to the Secret Page!</h2>
    <a href="/logout">Logout</a> <!-- 로그아웃 링크 -->
  </body>
</html>
  • 비밀 페이지: 로그인한 사용자만 접근할 수 있으며, logout 링크를 클릭하면 로그아웃됩니다.

4. 작동 흐름

  1. 사용자가 로그인 페이지에서 username과 password를 입력하고 로그인합니다.
  2. 로그인 정보가 정확하면 세션에 사용자 이름을 저장하고 비밀 페이지로 리디렉션합니다.
  3. 비밀 페이지는 세션에 username이 존재하는지 확인하여, 로그인된 사용자에게만 보여집니다.
  4. 로그아웃을 클릭하면 세션이 클리어되고 로그인 페이지로 리디렉션됩니다.

5. 보안 고려 사항

  • 세션 관리: 세션을 영구적으로 유지하는 경우, 사용자에게 중요한 정보가 노출되지 않도록 보안 강화가 필요합니다. 예를 들어, .env 파일을 사용하여 비밀 키를 보호하고, 세션을 암호화하는 방법을 적용할 수 있습니다.
  • 비밀번호 안전: 실제 배포 시, 사용자 비밀번호는 해시화하여 저장해야 합니다. 예를 들어, bcrypt 또는 werkzeug.security의 generate_password_hash와 check_password_hash를 사용하여 비밀번호를 안전하게 관리할 수 있습니다.

결론

  • Flask의 세션을 사용하여 사용자의 로그인 상태를 관리하고, 로그인/로그아웃 기능을 구현한 애플리케이션입니다.
  • 로그인 정보는 딕셔너리를 통해 확인하고, 세션을 통해 로그인 상태를 유지하며, 플래시 메시지를 사용하여 로그인 실패 시 사용자에게 피드백을 제공합니다.