-
Notifications
You must be signed in to change notification settings - Fork 1
[FEAT] 자동로그인 디버깅을 위한 토큰 로그 구현 (#276) #278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
bef3196
29c81b8
479678a
050abf7
58d4f8c
cdef896
718640f
26b666f
c921f6e
9538616
9e311d7
c99ec3c
414e35d
d1a7160
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,49 +16,52 @@ final class AuthManager { | |||||||
| private let refreshInterval: TimeInterval = 3 * 60 * 60 | ||||||||
|
|
||||||||
| var hasToken: Bool { | ||||||||
| return UserDefaultsManager.get(String.self, forKey: .accessToken) != nil | ||||||||
| return UserDefaultsUtils.get(String.self, forKey: .accessToken) != nil | ||||||||
| } | ||||||||
|
|
||||||||
| var hasVerifiedArea: Bool { | ||||||||
| return UserDefaultsManager.get(Bool.self, forKey: .hasVerifiedArea) ?? false | ||||||||
| return UserDefaultsUtils.get(Bool.self, forKey: .hasVerifiedArea) ?? false | ||||||||
| } | ||||||||
|
|
||||||||
| var hasPreference: Bool { | ||||||||
| return UserDefaultsManager.get(Bool.self, forKey: .hasPreference) ?? false | ||||||||
| return UserDefaultsUtils.get(Bool.self, forKey: .hasPreference) ?? false | ||||||||
| } | ||||||||
|
|
||||||||
| var hasSeenTutorial: Bool { | ||||||||
| return UserDefaultsManager.get(Bool.self, forKey: .hasSeenTutorial) ?? false | ||||||||
| return UserDefaultsUtils.get(Bool.self, forKey: .hasSeenTutorial) ?? false | ||||||||
| } | ||||||||
|
|
||||||||
| var hasSeenLocalVerification: Bool { | ||||||||
| return UserDefaultsManager.get(Bool.self, forKey: .hasSeenLocalVerification) ?? false | ||||||||
| return UserDefaultsUtils.get(Bool.self, forKey: .hasSeenLocalVerification) ?? false | ||||||||
| } | ||||||||
|
|
||||||||
| var hasSeenPreference: Bool { | ||||||||
| return UserDefaultsManager.get(Bool.self, forKey: .hasSeenPreference) ?? false | ||||||||
| return UserDefaultsUtils.get(Bool.self, forKey: .hasSeenPreference) ?? false | ||||||||
| } | ||||||||
|
|
||||||||
| func handleTokenRefresh() async throws -> Bool { | ||||||||
| let refreshToken = UserDefaultsManager.get(String.self, forKey: .refreshToken) ?? "" | ||||||||
| let refreshToken = UserDefaultsUtils.get(String.self, forKey: .refreshToken) ?? "" | ||||||||
| return try await withCheckedThrowingContinuation { continuation in | ||||||||
| ACService.shared.authService.postReissue(PostReissueRequest(refreshToken: refreshToken)) { response in | ||||||||
| switch response { | ||||||||
| case .success(let data): | ||||||||
| print("❄️ token refreshed success") | ||||||||
| UserDefaultsManager.set(data.accessToken, forKey: .accessToken) | ||||||||
| UserDefaultsManager.set(data.refreshToken, forKey: .refreshToken) | ||||||||
| UserDefaultsUtils.set(data.accessToken, forKey: .accessToken) | ||||||||
| UserDefaultsUtils.set(data.refreshToken, forKey: .refreshToken) | ||||||||
| AuthManager.shared.updateLastTokenRefreshDate() | ||||||||
| TokenLogger.shared.log(.refreshSucceeded(tokenPrefix: String(data.accessToken.prefix(10)))) | ||||||||
| continuation.resume(returning: true) | ||||||||
| case .requestErr(let error): | ||||||||
| if error.code == 40088 { | ||||||||
| print("❄️ remove token") | ||||||||
| UserDefaultsManager.removeTokens() | ||||||||
| UserDefaultsUtils.removeTokens() | ||||||||
| TokenLogger.shared.log(.refreshFailed(error: error.localizedDescription)) | ||||||||
| continuation.resume(returning: false) | ||||||||
| } else { | ||||||||
|
||||||||
| } else { | |
| } else { | |
| TokenLogger.shared.log(.refreshFailed(error: error.localizedDescription)) |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When needsTokenRefresh() returns true because lastTokenRefreshDate is nil (line 79), no token log is generated. This means the first-time login scenario after app installation won't be logged with a clear state. Consider adding TokenLogger.shared.log(.tokenExpired) or a more specific log event before returning true on line 79.
| guard let lastRefresh = UserDefaultsUtils.get(Date.self, forKey: .lastTokenRefreshDate) else { | |
| guard let lastRefresh = UserDefaultsUtils.get(Date.self, forKey: .lastTokenRefreshDate) else { | |
| TokenLogger.shared.log(.tokenExpired) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // | ||
| // BuildConfig.swift | ||
| // ACON-iOS | ||
| // | ||
| // Created by 김유림 on 10/14/25. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| enum BuildConfig { | ||
|
|
||
| #if DEBUG | ||
| static let isDebug = true | ||
| #else | ||
| static let isDebug = false | ||
| #endif | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging the first 10 characters of access tokens, even in debug/TestFlight builds, could pose a security risk. While this is limited to non-production builds, consider whether this amount of token information is necessary for debugging. A shorter prefix (e.g., 4-6 characters) or a hash of the token would be safer while still allowing token changes to be tracked.