[python] Peewee와 Flask의 인증 처리

웹 애플리케이션을 개발할 때, 사용자 인증 처리는 매우 중요한 요소입니다. Flask는 매우 인기 있는 Python 웹 프레임워크이며, Peewee는 간단하고 가볍게 사용할 수 있는 ORM(Object-Relational Mapping) 도구입니다. 이번 블로그 포스트에서는 Peewee와 Flask를 함께 사용하여 사용자 인증 처리를 구현하는 방법에 대해 알아보겠습니다.

Flask의 기본 인증 처리

Flask는 기본적으로 사용자 인증 처리를 위한 기능을 제공하지 않습니다. 하지만 Flask-Login이라는 확장을 사용하면 간단하게 인증 처리를 구현할 수 있습니다. Flask-Login은 사용자를 인증하고 로그인 상태를 유지하는데 도움을 주는 도구입니다.

먼저 Flask-Login을 설치해야 합니다. 다음 명령을 실행하여 설치할 수 있습니다:

pip install Flask-Login

다음으로, Flask-Login을 초기화하고 사용자 모델(User 모델)을 생성해야 합니다. User 모델은 데이터베이스에 사용자 정보를 저장하기 위한 모델입니다. Peewee를 사용하여 User 모델을 정의하고, Flask-Login의 UserMixin 클래스를 상속받아 필요한 메서드를 구현해야 합니다.

from peewee import *

db = SqliteDatabase('my_app.db')

class User(UserMixin, Model):
    username = CharField(unique=True)
    password = CharField()
    
    class Meta:
        database = db

이제 Flask 애플리케이션에 Flask-Login을 초기화하고 User 모델을 로드해야 합니다. 또한 로그인 뷰, 로그아웃 뷰 및 사용자 인증을 수행할 필요한 기능 등을 추가해야 합니다. 이러한 기능은 Flask-Login의 데코레이터를 사용하여 구현할 수 있습니다.

from flask_login import LoginManager, login_user, logout_user, login_required

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret_key'

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

@login_manager.user_loader
def load_user(user_id):
    return User.get(User.id == user_id)

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.get(User.username == username)
        
        if user and check_password(password, user.password):
            login_user(user)
            return redirect('/')
        
        flash('Invalid username or password', 'error')
        
    return render_template('login.html')

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect('/')

위의 예제에서는 login 뷰에서 POST 요청을 받아 사용자를 인증하고, 성공적으로 인증된 경우 사용자를 로그인 상태로 설정하며 메인 페이지로 리다이렉션합니다. 또한, logout 뷰에서는 로그아웃을 처리하고 메인 페이지로 리다이렉션합니다.

Peewee를 사용한 사용자 모델 생성 및 인증 처리

Flask-Login은 사용자 인증을 관리하는 기능을 제공합니다. 그러나 인증을 수행하기 위해 데이터베이스와 연동된 사용자 모델이 필요합니다. 이를 위해 Peewee를 사용하여 User 모델을 정의하고, 필요한 메서드를 구현해야 합니다.

from werkzeug.security import generate_password_hash, check_password_hash

class User(UserMixin, Model):
    username = CharField(unique=True)
    password_hash = CharField()

    @property
    def password(self):
        raise AttributeError('password is not readable')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

위의 예제에서는 password_hash 필드를 사용하여 비밀번호를 안전하게 저장하고, password 속성을 getter 및 setter로 구현하여 사용자의 비밀번호를 암호화 및 확인하는 기능을 추가했습니다.

로그인 인증 처리

사용자가 로그인하고나면, Flask-Login은 사용자를 세션에 저장하고 인증을 유지합니다. Peewee와 함께 사용할 때는, Flask-Login의 login_user 함수를 호출하여 사용자를 로그인 처리해야 합니다.

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        try:
            user = User.get(User.username == username)
        except User.DoesNotExist:
            flash('Invalid username or password', 'error')
            return redirect('/login')

        if user and user.verify_password(password):
            login_user(user)
            return redirect('/')
        
        flash('Invalid username or password', 'error')
        
    return render_template('login.html')

위의 예제에서는 login_user(user)를 호출하여 사용자를 로그인 처리합니다. 이때, user는 Peewee의 User 모델 인스턴스입니다.

로그아웃 처리

로그아웃은 간단하게 처리할 수 있습니다. Flask-Login의 logout_user 함수를 호출하여 현재 로그인된 사용자를 로그아웃 처리합니다.

@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect('/')

위의 예제에서는 logout_user()를 호출하여 현재 사용자를 로그아웃 처리하고, 메인 페이지로 리다이렉션합니다.

이제 Peewee와 Flask를 함께 사용하여 사용자 인증 처리를 구현하는 기본적인 방법에 대해 알아보았습니다. 이를 활용하여 웹 애플리케이션의 사용자 인증 처리를 보다 쉽고 간편하게 구현해보세요.

참고 자료