import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import '../../../core/storage/secure_storage.dart'; /// API 요청/응답 인터셉터 class ApiInterceptor extends Interceptor { final SecureStorage _storage; ApiInterceptor(this._storage); @override void onRequest( RequestOptions options, RequestInterceptorHandler handler, ) async { // 토큰 추가 final token = await _storage.getAccessToken(); if (token != null) { options.headers['Authorization'] = 'Bearer $token'; } // Content-Type 헤더 추가 if (options.data != null && options.data is! FormData) { options.headers['Content-Type'] = 'application/json'; } // 디버그 모드에서 요청 로깅 if (kDebugMode) { print('🚀 API Request: ${options.method} ${options.path}'); if (options.queryParameters.isNotEmpty) { print(' Query: ${options.queryParameters}'); } if (options.data != null) { print(' Body: ${options.data}'); } } handler.next(options); } @override void onResponse( Response response, ResponseInterceptorHandler handler, ) { // 디버그 모드에서 응답 로깅 if (kDebugMode) { print('✅ API Response: ${response.statusCode} ${response.requestOptions.path}'); if (response.data != null) { print(' Data: ${response.data}'); } } handler.next(response); } @override void onError( DioException err, ErrorInterceptorHandler handler, ) async { // 디버그 모드에서 에러 로깅 if (kDebugMode) { print('❌ API Error: ${err.requestOptions.path}'); print(' Error Type: ${err.type}'); print(' Message: ${err.message}'); if (err.response != null) { print(' Status: ${err.response?.statusCode}'); print(' Data: ${err.response?.data}'); } } // 401 Unauthorized 처리 if (err.response?.statusCode == 401) { // 토큰 갱신 시도 final refreshToken = await _storage.getRefreshToken(); if (refreshToken != null) { try { // 토큰 갱신 로직 (필요시 구현) // final newToken = await _refreshToken(refreshToken); // await _storage.saveTokens(newToken); // 원래 요청 재시도 // final options = err.requestOptions; // options.headers['Authorization'] = 'Bearer $newToken'; // final response = await dio.fetch(options); // return handler.resolve(response); } catch (e) { // 토큰 갱신 실패 시 로그아웃 처리 await _storage.clearAll(); } } else { // 리프레시 토큰이 없으면 로그아웃 처리 await _storage.clearAll(); } } handler.next(err); } }