주석화 진행상황 정리하고 핵심 모듈에 한글 주석 추가

This commit is contained in:
JiWoong Sul
2025-09-29 19:39:35 +09:00
parent 9467b8c87f
commit 47c87dc118
82 changed files with 596 additions and 5 deletions

View File

@@ -1,17 +1,21 @@
// ignore_for_file: public_member_api_docs
import 'dart:async';
import 'package:dio/dio.dart';
import '../../services/token_storage.dart';
/// 갱신 토큰을 기반으로 새로운 토큰 쌍을 받아오는 비동기 콜백 시그니처.
typedef RefreshTokenCallback = Future<TokenPair?> Function();
/// 액세스/리프레시 토큰 값을 함께 보관하기 위한 불변 모델.
class TokenPair {
/// [accessToken], [refreshToken]을 모두 전달받아 초기화한다.
const TokenPair({required this.accessToken, required this.refreshToken});
/// 인증 헤더에 사용되는 액세스 토큰 문자열.
final String accessToken;
/// 토큰 재발급 요청에 전달되는 리프레시 토큰 문자열.
final String refreshToken;
}
@@ -28,11 +32,17 @@ class AuthInterceptor extends Interceptor {
final TokenStorage _tokenStorage;
final Dio _dio;
/// 서버에 토큰 재발급을 요청하는 콜백. null이면 갱신을 시도하지 않는다.
final RefreshTokenCallback? onRefresh;
/// 동시에 들어온 요청을 순차적으로 처리하기 위한 대기열.
final List<Completer<void>> _refreshQueue = [];
/// 현재 토큰 갱신 중인지 여부.
bool _isRefreshing = false;
/// 요청 직전에 저장된 액세스 토큰을 Authorization 헤더에 주입한다.
@override
Future<void> onRequest(
RequestOptions options,
@@ -45,6 +55,7 @@ class AuthInterceptor extends Interceptor {
handler.next(options);
}
/// 401 응답을 감지하면 토큰을 갱신하고 동일 요청을 한 번 재시도한다.
@override
Future<void> onError(
DioException err,
@@ -69,12 +80,14 @@ class AuthInterceptor extends Interceptor {
}
}
/// 토큰 갱신을 시도해야 하는 상황인지 판별한다.
bool _shouldAttemptRefresh(DioException err) {
return onRefresh != null &&
err.response?.statusCode == 401 &&
err.requestOptions.extra['__retry'] != true;
}
/// 토큰을 갱신하고 대기 중인 요청을 깨운다.
Future<void> _refreshToken() async {
if (_isRefreshing) {
final completer = Completer<void>();
@@ -107,6 +120,7 @@ class AuthInterceptor extends Interceptor {
}
}
/// 최신 토큰을 헤더에 주입해 한 번만 동일 요청을 재시도한다.
Future<Response<dynamic>> _retry(RequestOptions requestOptions) async {
final token = await _tokenStorage.readAccessToken();
if (token != null && token.isNotEmpty) {
@@ -119,6 +133,7 @@ class AuthInterceptor extends Interceptor {
}
}
/// 토큰 재발급 실패 시 재시도 루프를 중단하기 위해 사용하는 내부 예외.
class _RefreshFailedException implements Exception {
const _RefreshFailedException();
}