[실습] 도커 실습 9 - Redis을 활용한 이기종 서버간 세션 공유
필기자
2024-11-13 10:48
152
0
본문
목차
- 파이썬 커스텀 도커 이미지 생성
- flask 프레임워크 로그인/로그아웃 app
- php 세션 공유 프로그램
파이썬 커스텀 도커 이미지 생성
- mkdir -p ~/flask/user
- cd ~/flask
- requirements.txt(python 패키지) 설정
Flask
Flask-Session
redis
PyMySQL
- Dockerfile 파일 생성
# Python 3.9 기반 이미지 사용
FROM python:3.9
# 작업 디렉토리 설정
WORKDIR /app
# 요구 사항 파일 복사 및 설치
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 애플리케이션 코드 복사
# COPY . .
# Flask 환경 변수 설정
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
# 컨테이너가 80 포트를 노출하도록 설정
EXPOSE 80
# Flask 애플리케이션 실행
CMD ["flask", "run", "--host=0.0.0.0", "--port=80"]
- 커스텀 이미지 생성
- docker build -t myflaskimage .
flask 프레임워크 로그인/로그아웃 app
- nano ~/flask/user/app.py
from flask import Flask, request, jsonify
import pymysql
import redis
app = Flask(__name__)
app.url_map.strict_slashes = False # 슬래시 구분을 비활성화
# Redis 설정
session_id = "cloud-native"
redis_client = redis.StrictRedis(host='myredis', port=6379, decode_responses=True) # decode_responses=True로 설정해 문자열 데이터를 반환받음
# MySQL 연결 설정 (예외 처리 추가)
try:
connection = pymysql.connect(
host='mysql',
user='php-mysql',
password='123456',
database='php-mysql',
cursorclass=pymysql.cursors.DictCursor
)
except pymysql.MySQLError as e:
print(f"Error connecting to MySQL: {e}")
connection = None
# 기본 테스트 페이지 라우트
@app.route('/', methods=['GET'])
def user_home():
return "Welcome to the User Home Page! This is a test page."
# 로그인 라우트 (GET 및 POST 요청 허용)
@app.route('/login', methods=['GET', 'POST'])
def login():
global session_id, redis_client
ret = {}
if request.method == 'GET':
email = request.args.get('email', '')
password = request.args.get('password', '')
else:
email = request.form.get('email', '')
password = request.form.get('password', '')
if not email:
ret['result'] = "no"
ret['msg'] = "이메일 정보가 없습니다."
return jsonify(ret)
if not password:
ret['result'] = "no"
ret['msg'] = "패스워드 정보가 없습니다."
return jsonify(ret)
password = str(password)
if connection is None:
ret['result'] = "no"
ret['msg'] = "데이터베이스에 연결할 수 없습니다."
return jsonify(ret)
try:
with connection.cursor() as cursor:
query = "SELECT * FROM user WHERE email=%s AND pass=%s"
cursor.execute(query, (email, password))
row = cursor.fetchone()
if not row:
ret['result'] = "no"
ret['msg'] = "로그인 정보가 틀립니다."
else:
# Redis에 세션 데이터 저장 (1시간 동안 저장)
redis_client.setex(f"session:{session_id}:username", 3600, row['name'])
redis_client.setex(f"session:{session_id}:useremail", 3600, row['email'])
ret['result'] = "ok"
ret['msg'] = "정상 로그인이 되었습니다."
except pymysql.MySQLError as e:
ret['result'] = "no"
ret['msg'] = "데이터베이스 쿼리 오류: " + str(e)
except Exception as e:
ret['result'] = "no"
ret['msg'] = "일반적인 오류: " + str(e)
finally:
if connection:
connection.commit()
return jsonify(ret)
# 로그아웃 라우트
@app.route('/logout', methods=['POST'])
def logout():
global session_id, redis_client
ret = {}
try:
# Redis에서 세션 데이터 삭제
redis_client.delete(f"session:{session_id}:username")
redis_client.delete(f"session:{session_id}:useremail")
ret['result'] = "ok"
ret['msg'] = "로그아웃이 완료되었습니다."
print("Session data cleared") # 디버깅 메시지
except Exception as e:
ret['result'] = "no"
ret['msg'] = "로그아웃 중 오류가 발생했습니다: " + str(e)
print(f"Error during logout: {e}") # 디버깅 메시지
return jsonify(ret)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80, debug=True)
- 기존 myuserapi 컨테이너 삭제
- flask 컨터이너 생성
- docker run -d --name myuserapi -p 8013:80 --net php-mysql -v /home/kkl/flask/user:/app myflaskimage
- http://gctask.com/user/login?email=aaa@aaa.com&password=2323 으로 로그인
- 개발 단계에서 테스트 get 허용
php 세션 공유 프로그램
- nano ~/php/task/redis_session_get.php
// Redis에 연결
$redis = new Redis();
$redis->connect('myredis', 6379);
// 세션 ID 설정 (Flask에서 사용한 것과 동일한 값)
$session_id = "cloud-native";
// Redis에서 세션 데이터 가져오기
$username = $redis->get("session:$session_id:username");
$useremail = $redis->get("session:$session_id:useremail");
echo "사용자 이름 : " . ($username ? $username : '없음') . "<br>";
echo "사용자 아이디 : " . ($useremail ? $useremail : '없음') . "<br>";
댓글목록0