forked from baron/baron-sso
#269 진행. 리다이렉트 등 파라미터 전체 전달
This commit is contained in:
51
docs/trouble-shooting/issue-269-locale-query-loss.md
Normal file
51
docs/trouble-shooting/issue-269-locale-query-loss.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Issue #269 해결 기록: `/{locale}/` 도입 후 query parameter 유실
|
||||
|
||||
## 개요
|
||||
- 대상 이슈: `#269`
|
||||
- 증상: locale 보정 또는 비로그인 리다이렉트 과정에서 GET query parameter가 유실되거나 형태가 변형됨
|
||||
- 영향: OIDC 로그인 연계 파라미터(`login_challenge`, `redirect_uri`, `notice` 등) 전달 실패 가능
|
||||
|
||||
## 원인
|
||||
1. 비로그인 리다이렉트 시 `login_challenge`만 선택 보존하고 나머지 query를 폐기
|
||||
2. locale 경로 재작성 시 `uri.queryParameters` 기반 재직렬화로 원본 query 문자열(중복 key, 순서, 인코딩) 보존 실패
|
||||
3. `head.length == 2` 휴리스틱으로 locale이 아닌 2글자 경로 prefix까지 locale로 오인 가능
|
||||
|
||||
## 수정 사항
|
||||
|
||||
### 1) 비로그인 리다이렉트에서 raw query 전체 보존
|
||||
- 파일: `userfront/lib/main.dart`
|
||||
- 변경: `state.uri.query`를 그대로 `/[locale]/signin`에 연결
|
||||
|
||||
```dart
|
||||
final rawQuery = state.uri.query;
|
||||
if (rawQuery.isNotEmpty) {
|
||||
return '/$locale/signin?$rawQuery';
|
||||
}
|
||||
return '/$locale/signin';
|
||||
```
|
||||
|
||||
### 2) locale 경로 재작성 시 raw query/fragment 보존
|
||||
- 파일: `userfront/lib/core/i18n/locale_utils.dart`
|
||||
- 변경: `queryParameters` 재직렬화 제거, `uri.query`/`uri.fragment` 원문 유지
|
||||
|
||||
```dart
|
||||
final queryPart = uri.hasQuery ? '?${uri.query}' : '';
|
||||
final fragmentPart = uri.fragment.isNotEmpty ? '#${uri.fragment}' : '';
|
||||
return '$path$queryPart$fragmentPart';
|
||||
```
|
||||
|
||||
### 3) locale 판별 조건 엄격화
|
||||
- 파일: `userfront/lib/core/i18n/locale_utils.dart`
|
||||
- 변경: `head.length == 2` 휴리스틱 제거, `supportedLocaleCodes.contains(head)`만 허용
|
||||
|
||||
## 테스트 보강
|
||||
- 파일: `userfront/test/locale_utils_test.dart`
|
||||
- 추가/변경:
|
||||
- raw query 순서 및 중복 key(`a=1&a=2`) 보존
|
||||
- fragment 보존
|
||||
- unknown 2-letter prefix(`zz`)를 locale로 제거하지 않음
|
||||
|
||||
## 기대 결과
|
||||
- `/signin?redirect_uri=...¬ice=...` -> locale 보정 후 query 100% 유지
|
||||
- 비로그인 보호 경로 -> `/[locale]/signin` 이동 시 기존 query 유지
|
||||
- 인코딩된 nested `redirect_uri`, 중복 query key, fragment 보존
|
||||
54
docs/trouble-shooting/issue-269-test-scenarios.md
Normal file
54
docs/trouble-shooting/issue-269-test-scenarios.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Issue #269 테스트 시나리오
|
||||
|
||||
## 목적
|
||||
`/{locale}/` 라우팅 도입 이후 query parameter 유실 회귀를 방지합니다.
|
||||
|
||||
## 범위
|
||||
- UserFront locale 경로 보정 (`buildLocalizedPath`)
|
||||
- 비로그인 redirect 경로 생성 (`buildSigninRedirectPath`)
|
||||
- locale 지원 목록 동기화 (`assets/translations/*.toml` -> `LocaleRegistry`)
|
||||
|
||||
## 테스트 시나리오
|
||||
|
||||
### S1. locale 보정 시 기본 query 보존
|
||||
- 입력: `/signin?redirect_uri=https://example.com`
|
||||
- 기대: `/ko/signin?redirect_uri=https://example.com`
|
||||
|
||||
### S2. locale 보정 시 raw query 순서/중복 key 보존
|
||||
- 입력: `/signin?a=1&a=2&redirect_uri=https%3A%2F%2Fexample.com%2Fcb%3Fx%3D1%26y%3D2`
|
||||
- 기대: `/ko/signin?a=1&a=2&redirect_uri=https%3A%2F%2Fexample.com%2Fcb%3Fx%3D1%26y%3D2`
|
||||
|
||||
### S3. locale 보정 시 fragment 보존
|
||||
- 입력: `/signin?notice=qr_login_required#auth`
|
||||
- 기대: `/ko/signin?notice=qr_login_required#auth`
|
||||
|
||||
### S4. unknown 2-letter prefix 오인 제거
|
||||
- 입력: `/zz/signin`
|
||||
- 기대: `/ko/zz/signin`
|
||||
|
||||
### S5. 비로그인 redirect에서 query 없음
|
||||
- 입력: locale=`ko`, uri=`/ko/profile`
|
||||
- 기대: `/ko/signin`
|
||||
|
||||
### S6. 비로그인 redirect에서 query 전체 보존
|
||||
- 입력: locale=`ko`, uri=`/ko/profile?a=1&a=2&redirect_uri=https%3A%2F%2Fexample.com%2Fcb%3Fx%3D1%26y%3D2¬ice=qr_login_required`
|
||||
- 기대: `/ko/signin?a=1&a=2&redirect_uri=https%3A%2F%2Fexample.com%2Fcb%3Fx%3D1%26y%3D2¬ice=qr_login_required`
|
||||
|
||||
### S7. locale 목록 하드코딩 제거 검증
|
||||
- 입력: asset 목록 (`assets/translations/en.toml`, `assets/translations/ko.toml`, `assets/translations/template.toml`, 기타 invalid 파일)
|
||||
- 기대:
|
||||
- `template.toml` 제외
|
||||
- 유효 locale 파일(`en.toml`, `ko.toml`)만 지원 목록에 반영
|
||||
|
||||
## 실행 방법
|
||||
```bash
|
||||
cd userfront
|
||||
flutter test test/locale_utils_test.dart
|
||||
flutter test test/locale_registry_test.dart
|
||||
```
|
||||
|
||||
## 자동화 매핑
|
||||
- `userfront/test/locale_utils_test.dart`
|
||||
- S1~S6 전부 커버
|
||||
- `userfront/test/locale_registry_test.dart`
|
||||
- S7 커버
|
||||
Reference in New Issue
Block a user