파이썬 Flask에서 세션, 로그인, 로그아웃 구현

Flask는 간단하고 유연한 파이썬 웹 프레임워크로, 세션 관리 및 사용자 인증 기능을 쉽게 구현할 수 있습니다. 이 기능을 활용하여 웹 애플리케이션에서 로그인, 로그아웃을 구현하고 사용자의 상태를 관리할 수 있습니다.

1. Flask 세션이란?

세션(session)은 클라이언트가 웹 애플리케이션에 접속한 후, 서버에서 클라이언트와의 상호작용 상태를 유지하기 위한 저장 공간입니다. Flask에서는 session 객체를 사용하여 세션 데이터를 저장할 수 있으며, 이 데이터는 클라이언트의 쿠키에 저장됩니다. Flask는 쿠키의 무결성을 보장하기 위해 비밀 키(Secret Key)를 사용하여 세션 데이터를 서명합니다.

2. Flask-Login이란?

Flask-Login은 Flask 애플리케이션에서 사용자 로그인, 로그아웃, 세션 관리 등을 쉽게 구현할 수 있는 확장 라이브러리입니다. 주로 사용자의 인증 및 세션 관리를 다룹니다.

주요 기능:

  • 사용자 로그인 및 로그아웃 관리
  • 사용자 세션 유지 (로그인 상태)
  • 로그인하지 않은 사용자에 대한 페이지 접근 제한
  • Remember Me 기능을 통한 지속적인 로그인 세션

설치

pip install flask flask-login

3. 기본 Flask 세션 및 로그인 예제

다음은 기본적인 Flask에서의 세션과 로그인, 로그아웃 구현 예제입니다.

from flask import Flask, render_template, redirect, url_for, request, session, flash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

app = Flask(__name__)

# 세션을 위한 비밀 키 설정
app.secret_key = 'your_secret_key'

# Flask-Login 설정
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'  # 로그인 페이지 경로 설정

# 사용자 정보를 담을 가상의 사용자 데이터베이스 (딕셔너리 형태로 간단히 구현)
users = {
    'admin': {'password': 'secret'}
}

# 사용자 클래스를 정의
class User(UserMixin):
    def __init__(self, username):
        self.id = username

# Flask-Login은 사용자를 로드하는 함수 필요
@login_manager.user_loader
def load_user(username):
    if username in users:
        return User(username)
    return None

# 홈 페이지
@app.route('/')
@login_required
def home():
    return f'Hello, {current_user.id}! You are logged in.'

# 로그인 페이지
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        # 사용자 인증
        if username in users and users[username]['password'] == password:
            user = User(username)
            login_user(user)  # 로그인 처리
            flash('Logged in successfully!')
            return redirect(url_for('home'))  # 로그인 후 홈으로 이동
        else:
            flash('Invalid username or password')  # 잘못된 로그인 정보

    return render_template('login.html')

# 로그아웃 처리
@app.route('/logout')
@login_required
def logout():
    logout_user()  # Flask-Login에서 제공하는 로그아웃 함수
    flash('You have been logged out.')
    return redirect(url_for('login'))

# 로그인 상태에서만 접근 가능한 페이지
@app.route('/protected')
@login_required
def protected():
    return 'This is a protected page. Only logged-in users can see this.'

# 서버 실행
if __name__ == '__main__':
    app.run(debug=True)

4. 코드 설명

1. Flask 기본 설정

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # 세션을 위한 비밀 키

Flask 애플리케이션을 생성하고, 세션 데이터 보호를 위해 secret_key를 설정합니다. 이 키는 세션 데이터를 서명하여 조작되지 않도록 보호합니다.

2. Flask-Login 설정

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'

Flask-Login의 인스턴스를 생성하고, Flask 애플리케이션에 등록합니다. login_view는 로그인하지 않은 사용자가 접근할 수 없는 페이지에 접근할 때 리디렉션될 로그인 페이지 경로입니다.

3. 사용자 클래스 정의 (UserMixin)

class User(UserMixin):
    def __init__(self, username):
        self.id = username

Flask-LoginUserMixin을 사용하는 User 클래스를 요구합니다. 이 클래스는 로그인한 사용자의 ID를 관리하고 UserMixin을 상속받아 여러 유틸리티 메서드를 사용할 수 있습니다.

4. 로그인 사용자 로드 함수

@login_manager.user_loader
def load_user(username):
    if username in users:
        return User(username)
    return None

Flask-Login은 사용자 정보를 세션에서 가져오기 위해 사용자 로딩 함수가 필요합니다. 이 함수는 사용자 ID를 사용해 사용자를 데이터베이스에서 가져옵니다.

5. 로그인 처리

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        # 사용자 인증
        if username in users and users[username]['password'] == password:
            user = User(username)
            login_user(user)
            flash('Logged in successfully!')
            return redirect(url_for('home'))
        else:
            flash('Invalid username or password')

    return render_template('login.html')
  • 로그인 페이지는 GET 요청 시 화면에 표시됩니다.
  • POST 요청 시, 사용자 입력 정보를 통해 인증을 수행하고, 인증 성공 시 login_user()를 통해 세션을 시작합니다.

6. 로그아웃 처리

@app.route('/logout')
@login_required
def logout():
    logout_user()  # Flask-Login에서 제공하는 로그아웃 함수
    flash('You have been logged out.')
    return redirect(url_for('login'))
  • logout_user()를 호출하여 사용자의 세션을 종료합니다.

7. 로그인 필수 데코레이터 (@login_required)

@app.route('/protected')
@login_required
def protected():
    return 'This is a protected page. Only logged-in users can see this.'

@login_required 데코레이터를 사용하여 로그인한 사용자만 접근할 수 있는 페이지를 정의할 수 있습니다. 로그인하지 않은 사용자가 이 페이지에 접근하려고 하면 login_view로 리디렉션됩니다.

5. 로그인 페이지 템플릿 (login.html)

로그인 화면을 위한 간단한 HTML 템플릿입니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
</head>
<body>
    <h2>Login</h2>
    <form method="POST" action="/login">
        <label for="username">Username:</label>
        <input type="text" name="username" id="username" required>
        <br>
        <label for="password">Password:</label>
        <input type="password" name="password" id="password" required>
        <br>
        <button type="submit">Login</button>
    </form>

    {% with messages = get_flashed_messages() %}
      {% if messages %}
        <ul>
        {% for message in messages %}
          <li>{{ message }}</li>
        {% endfor %}
        </ul>
      {% endif %}
    {% endwith %}
</body>
</html>

설명:

  • 사용자 이름과 비밀번호를 입력받고 POST 요청으로 로그인 폼을 제출합니다.
  • 로그인 시 오류가 있으면 Flash 메시지를 통해 사용자에게 알립니다.

결론

이 예제에서는 Flask 세션Flask-Login을 사용하여 로그인과 로그아웃 기능을 구현하는 방법을 다뤘습니다. Flask-Login은 로그인한 사용자 세션을 관리하고, 로그인하지 않은 사용자가 접근할 수 없는 페이지를 보호하는 데 매우 유용합니다. 비동기 작업이나 데이터베이스 연동 등과 함께 사용할 수 있으며, 더 복잡한 인증 시스템을 구현할 때 매우 유용한 도구입니다.

추가적으로 구현하고 싶은 기능이나 질문이 있으면 언제든지 알려주세요!

+ Recent posts