David Ko commited on
Commit
7ac53fe
ยท
1 Parent(s): 64663bd

Fix login redirect loop with Flask-Session and improved routing

Browse files
Files changed (2) hide show
  1. api.py +30 -13
  2. requirements.txt +1 -0
api.py CHANGED
@@ -43,6 +43,13 @@ login_manager.init_app(app)
43
  login_manager.login_view = 'login'
44
  login_manager.session_protection = 'strong'
45
 
 
 
 
 
 
 
 
46
  # ์‚ฌ์šฉ์ž ํด๋ž˜์Šค ์ •์˜
47
  class User(UserMixin):
48
  def __init__(self, id, username, password):
@@ -1129,7 +1136,7 @@ def login():
1129
  # ์ด๋ฏธ ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜
1130
  if current_user.is_authenticated:
1131
  print(f"User already authenticated as: {current_user.username}, redirecting to index")
1132
- return redirect('/index')
1133
 
1134
  error = None
1135
  if request.method == 'POST':
@@ -1153,8 +1160,8 @@ def login():
1153
  if next_page and next_page.startswith('/') and next_page != '/login':
1154
  print(f"Redirecting to: {next_page}")
1155
  return redirect(next_page)
1156
- print("Redirecting to static index.html")
1157
- return send_from_directory(app.static_folder, 'index.html')
1158
  else:
1159
  error = 'Invalid username or password'
1160
  print(f"Login failed: {error}")
@@ -1166,21 +1173,31 @@ def logout():
1166
  logout_user()
1167
  return redirect(url_for('login'))
1168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1169
  @app.route('/', defaults={'path': ''}, methods=['GET'])
1170
  @app.route('/<path:path>', methods=['GET'])
1171
  @login_required
1172
  def serve_react(path):
1173
  """Serve React frontend"""
1174
  print(f"Serving React frontend for path: {path}, user: {current_user.username if current_user.is_authenticated else 'not authenticated'}")
1175
- # Handle static files directly
1176
- if path.startswith('static/'):
1177
- file_path = path[7:] # Remove 'static/' prefix
1178
- return send_from_directory(app.static_folder, file_path)
1179
- # Handle other static files in root of static folder
1180
- elif path != "" and os.path.exists(os.path.join(app.static_folder, path)):
1181
  return send_from_directory(app.static_folder, path)
1182
  else:
1183
- # Serve the React app's index.html for all other routes
1184
  return send_from_directory(app.static_folder, 'index.html')
1185
 
1186
  @app.route('/similar-images', methods=['GET'])
@@ -1221,9 +1238,9 @@ def status():
1221
  @app.route('/index')
1222
  @login_required
1223
  def index_page():
1224
- # /index ๊ฒฝ๋กœ๋„ ๋ฃจํŠธ ๊ฒฝ๋กœ์™€ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌ
1225
- print("Index route redirecting to root")
1226
- return redirect('/')
1227
 
1228
  if __name__ == "__main__":
1229
  # ํ—ˆ๊น…ํŽ˜์ด์Šค Space์—์„œ๋Š” PORT ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค
 
43
  login_manager.login_view = 'login'
44
  login_manager.session_protection = 'strong'
45
 
46
+ # ์„ธ์…˜ ์„ค์ •
47
+ from flask_session import Session
48
+ app.config['SESSION_TYPE'] = 'filesystem'
49
+ app.config['SESSION_PERMANENT'] = True
50
+ app.config['SESSION_USE_SIGNER'] = True
51
+ Session(app)
52
+
53
  # ์‚ฌ์šฉ์ž ํด๋ž˜์Šค ์ •์˜
54
  class User(UserMixin):
55
  def __init__(self, id, username, password):
 
1136
  # ์ด๋ฏธ ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋Š” ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜
1137
  if current_user.is_authenticated:
1138
  print(f"User already authenticated as: {current_user.username}, redirecting to index")
1139
+ return redirect('/index.html')
1140
 
1141
  error = None
1142
  if request.method == 'POST':
 
1160
  if next_page and next_page.startswith('/') and next_page != '/login':
1161
  print(f"Redirecting to: {next_page}")
1162
  return redirect(next_page)
1163
+ print("Redirecting to index.html")
1164
+ return redirect('/index.html')
1165
  else:
1166
  error = 'Invalid username or password'
1167
  print(f"Login failed: {error}")
 
1173
  logout_user()
1174
  return redirect(url_for('login'))
1175
 
1176
+ # ์ •์  ํŒŒ์ผ ์„œ๋น™์„ ์œ„ํ•œ ๋ผ์šฐํŠธ (๋กœ๊ทธ์ธ ๋ถˆํ•„์š”)
1177
+ @app.route('/static/<path:filename>')
1178
+ def serve_static(filename):
1179
+ print(f"Serving static file: {filename}")
1180
+ return send_from_directory(app.static_folder, filename)
1181
+
1182
+ # ์ธ๋ฑ์Šค HTML ์ง์ ‘ ์„œ๋น™ (๋กœ๊ทธ์ธ ํ•„์š”)
1183
+ @app.route('/index.html')
1184
+ @login_required
1185
+ def serve_index_html():
1186
+ print(f"Serving index.html for user: {current_user.username if current_user.is_authenticated else 'not authenticated'}")
1187
+ return send_from_directory(app.static_folder, 'index.html')
1188
+
1189
+ # ๊ธฐ๋ณธ ๊ฒฝ๋กœ ๋ฐ ๊ธฐํƒ€ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ (๋กœ๊ทธ์ธ ํ•„์š”)
1190
  @app.route('/', defaults={'path': ''}, methods=['GET'])
1191
  @app.route('/<path:path>', methods=['GET'])
1192
  @login_required
1193
  def serve_react(path):
1194
  """Serve React frontend"""
1195
  print(f"Serving React frontend for path: {path}, user: {current_user.username if current_user.is_authenticated else 'not authenticated'}")
1196
+ # ์ •์  ํŒŒ์ผ ์ฒ˜๋ฆฌ๋Š” ์ด์ œ ๋ณ„๋„ ๋ผ์šฐํŠธ์—์„œ ์ฒ˜๋ฆฌ
1197
+ if path != "" and os.path.exists(os.path.join(app.static_folder, path)):
 
 
 
 
1198
  return send_from_directory(app.static_folder, path)
1199
  else:
1200
+ # React ์•ฑ์˜ index.html ์„œ๋น™
1201
  return send_from_directory(app.static_folder, 'index.html')
1202
 
1203
  @app.route('/similar-images', methods=['GET'])
 
1238
  @app.route('/index')
1239
  @login_required
1240
  def index_page():
1241
+ # /index ๊ฒฝ๋กœ๋Š” index.html๋กœ ๋ฆฌ๋””๋ ‰์…˜
1242
+ print("Index route redirecting to index.html")
1243
+ return redirect('/index.html')
1244
 
1245
  if __name__ == "__main__":
1246
  # ํ—ˆ๊น…ํŽ˜์ด์Šค Space์—์„œ๋Š” PORT ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค
requirements.txt CHANGED
@@ -12,6 +12,7 @@ timm>=0.9.0 # Vision Transformer support
12
  flask>=2.0.0
13
  flask-cors>=3.0.0
14
  flask-login>=0.6.2
 
15
  matplotlib>=3.5.0
16
  numpy>=1.20.0
17
 
 
12
  flask>=2.0.0
13
  flask-cors>=3.0.0
14
  flask-login>=0.6.2
15
+ flask-session>=0.4.0
16
  matplotlib>=3.5.0
17
  numpy>=1.20.0
18