주로 웹 서버(web server)를 위한 웹 프레임워크(web framework) 라이브러리
장점: 가볍다.
단점: 대규모 프로젝트에 한계가 있다.
1. 설치
pip install Flask
2. 기본 사용법
from flask import Flask
# Flask 객체 생성. __name__은 현재 모듈의 이름
app = Flask(__name__)
@app.route('/') # 해당 경로에서 실행
def main():
# 브라우저에 반환할 내용
return 'Hello, World!'
# 서버 실행
# 이 스크립트가 직접 실행될 때만 (import될 때가 아닌) 서버를 구동
if __name__ == '__main__':
app.run(debug=True)
3. 라우팅 (Routing)
1. 기본 라우팅
@app.route('/about')
def about_page():
return '이것은 About 페이지입니다.'
2. 동적 라우팅
@app.route('/user/<username>')
def show_user_profile(username):
# f-string을 사용하여 변수를 출력
return f'사용자: {username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# <int:post_id>처럼 데이터 타입을 지정할 수 있습니다.
return f'게시글 번호: {post_id}'
3. GET, POST 지정
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 폼(Form) 데이터를 처리하는 로직
username = request.form.get('username')
return f'{username}님, 로그인 성공!'
else:
# 로그인 폼을 보여주는 로직 (일반적인 GET 요청)
return '여기는 로그인 페이지입니다. 폼을 보여줄 예정.'
4. 템플릿 (Templates)
templates 폴더에서 템플릿 파일 사용 ( ex: templates/index.html )
render_template 함수 임포트 및 사용
from flask import Flask, render_templateapp = Flask(__name__)
return render_template('index.html', name=name)
탬플릿 문법
| 문법 | 용도 | 예시 |
| {{ expression }} | 변수 또는 표현식의 값을 출력 | <h1>Hello, {{ name }}!</h1> |
| {% statement %} | 조건문(if), 반복문(for) 등의 제어 구조 | {% if user %}…{% endif %} |
| {# comment #} | 주석 (HTML 출력에 포함되지 않음) | {# 이 부분은 사용자에게 보이지 않음 #} |
5. 정적 파일 (Static Files)
- 정적 파일 저장:
- static/css/style.css
- static/images/logo.png
- 템플릿에서 정적 파일 링크:HTML 템플릿 내에서 Flask의 내장 함수 url_for()를 사용하여 정적 파일의 URL을 생성
- <link rel=”stylesheet” href=”{{ url_for(‘static’, filename=’css/style.css’) }}”>
- <img src=”{{ url_for(‘static’, filename=’images/logo.png’) }}” alt=”로고”>
6. 데이터베이스 연동 (Flask-SQLAlchemy)
설치: pip install Flask-SQLAlchemy
설정: 애플리케이션에 데이터베이스 연결 URI를 설정 (예: SQLite, PostgreSQL, MySQL)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
모델 정의: 데이터베이스 테이블에 해당하는 파이썬 클래스를 정의
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
데이터 조작: 세션(Session)을 사용하여 데이터 CRUD
# 데이터 추가
new_user = User(username='test_user')
db.session.add(new_user)
db.session.commit()
# 데이터 조회
all_users = User.query.all()
specific_user = User.query.filter_by(username='test_user').first()
마이그레이션 (Migration): Flask-Migrate를 사용하여 데이터베이스 스키마(테이블 구조) 변경을 관리
설치: pip install Flask-Migrate
7. 폼 (Flask-WTF)
설치: pip install Flask-WTF
폼 클래스 정의
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, validators
class LoginForm(FlaskForm):
username = StringField('아이디', [validators.DataRequired()])
password = PasswordField('비밀번호', [validators.DataRequired()])
submit = SubmitField('로그인')
템플릿 렌더링: 렌더링 및 CSRF 보호를 위해 {{ form.hidden_tag() }}를 추가
데이터 처리
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit(): # 유효성 검사 성공 시 데이터 처리
print(f'사용자 이름: {form.username.data}')
return redirect(url_for('home'))
return render_template('login.html', form=form)
사용자 인증
설치: pip install Flask-Login
설정: LoginManager를 초기화하고 애플리케이션과 연결
User 모델 통합: Flask-SQLAlchemy로 정의한 사용자 모델에 UserMixin을 상속받아 Flask-Login이 필요로 하는 속성(예: is_authenticated)을 추가
사용자 로더: 세션에 저장된 사용자 ID를 기반으로 실제 사용자 객체를 로드하는 함수를 정의
인증 로직:
- 로그인: login_user(user) 함수를 호출하여 사용자를 로그인 상태로 만듬
- 페이지 보호: @login_required 데코레이터를 사용하여 특정 라우트 함수에 로그인 필터링을 적용
from flask_login import login_user, login_required, current_user
@app.route('/dashboard')
@login_required # 로그인한 사용자만 접근 가능
def dashboard():
return f'환영합니다, {current_user.username}님!'
8. 세션, 쿠키 (Session, cookie)
1. 세션 (Session)
Flask의 세션은 쿠키를 사용하여 데이터를 저장하지만, 실제 데이터는 서명(Signed)되어 브라우저에 저장. 세션을 사용하려면 반드시 SECRET_KEY가 설정되어야 함.
A. 세션 설정
세션을 사용하기 위해 애플리케이션에 비밀 키를 설정합니다.
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
# 세션 데이터를 안전하게 서명하는 데 필수적입니다.
# 실제 배포 시에는 복잡하고 무작위적인 문자열을 사용해야 합니다.
app.config['SECRET_KEY'] = 'my_super_secret_key_1234'
B. 세션 데이터 조작
| 작업 | 설명 | 예시 코드 |
| 저장 | 세션에 데이터를 저장합니다. | session[‘user_id’] = 101 |
| 조회 | 세션에서 값을 가져옵니다. | user_id = session.get(‘user_id’) |
| 제거 | 특정 세션 값을 삭제합니다. | session.pop(‘user_id’, None) |
| 전체 초기화 | 모든 세션 데이터를 삭제합니다. | session.clear() |
C. 세션 예시 코드
@app.route('/login', methods=['POST'])
def login():
# 로그인 성공 가정 후, 사용자 ID를 세션에 저장
if request.form.get('password') == '1234':
session['username'] = request.form.get('username')
session['logged_in'] = True
return '로그인 성공. 세션 저장됨.'
return '로그인 실패'
@app.route('/whoami')
def who_am_i():
# 'logged_in' 키를 확인하여 로그인 상태 체크
if session.get('logged_in'):
# escape()로 출력하여 XSS 공격을 방지합니다.
return f'현재 사용자: {escape(session.get("username"))}'
return '로그인되지 않았습니다.'
@app.route('/logout')
def logout():
# 세션에 저장된 모든 정보를 삭제
session.clear()
return redirect(url_for('who_am_i'))
2. 쿠키 (Cookie)
Flask에서 쿠키를 설정할 때는 응답(Response) 객체, 읽을 때는 요청(Request) 객체를 사용.
A. 쿠키 설정 (저장)
from flask import make_response
@app.route('/set_cookie')
def set_cookie():
response = make_response('쿠키가 설정되었습니다.')
# 1. 일반 쿠키 설정 (보안에 취약)
response.set_cookie('last_visit', '2025-10-26', max_age=60*60*24*7) # 7일 유지
# 2. Signed 쿠키 설정 (위변조 방지)
# secure=True로 설정하면 브라우저는 HTTP 환경에서 이 쿠키를 서버에 전송하지 않습니다.
response.set_cookie('preference', 'dark_mode', max_age=3600, httponly=True, samesite='Lax')
return response
- max_age: 쿠키의 유효 기간(초 단위) 설정 (기본값: 브라우저 종료 시 삭제)
- httponly: JavaScript 접근을 막아 XSS 공격 방어에 도움을 줌. (권장)
- secure: HTTPS 연결에서만 쿠키를 전송하도록 설정
B. 쿠키 읽기, 삭제
from flask import request
@app.route('/get_cookie')
def get_cookie():
# request.cookies.get()을 사용하여 쿠키 값을 가져옵니다.
last_visit = request.cookies.get('last_visit')
if last_visit:
return f'마지막 방문일: {last_visit}'
return '방문 쿠키가 없습니다.'
@app.route('/delete_cookie')
def delete_cookie():
response = make_response('쿠키가 삭제되었습니다.')
# max_age를 0으로 설정하여 쿠키를 즉시 만료시키고 삭제
response.set_cookie('last_visit', '', max_age=0)
return response
3. 세션 vs 쿠키 요약(권장)
| 특징 | 세션 (session) | 쿠키 (cookie) |
| 보안 | 높음 (데이터 서명 및 암호화) | 낮음 (일반 텍스트로 저장) |
| 사용 목적 | 인증 상태 (로그인 여부), 민감하지 않은 사용자 데이터 | 개인 설정 (테마, 언어), 방문 기록 |
| 저장 방식 | 서버에서 생성, 서명된 쿠키로 브라우저에 저장 | 서버에서 생성, 일반 텍스트 쿠키로 브라우저에 저장 |
| 설정 | SECRET_KEY가 필수 | 응답 객체를 사용하여 수동 설정 |
댓글 남기기