Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions Projects/Feature/Sources/Extension/GOMSRefreshToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Copyright ยฉ 2026 HARIBO. All rights reserved.
//

import UIKit
import Foundation
import Moya
import Service

Expand Down Expand Up @@ -68,17 +70,35 @@ public final class GOMSRefreshToken {
}

private func updateKeychainToken() {
let newAccessToken = reissuanceData?.accessToken ?? ""
let newRefreshToken = reissuanceData?.refreshToken ?? ""

let accessTokenUpdated = keychain.updateItem(
token: reissuanceData?.accessToken ?? "",
token: newAccessToken,
key: Const.KeyChainKey.accessToken
)

let refreshTokenUpdated = keychain.updateItem(
token: reissuanceData?.refreshToken ?? "",
token: newRefreshToken,
key: Const.KeyChainKey.refreshToken
)

// ์ƒˆ accessToken์˜ JWT payload์—์„œ role์„ ํŒŒ์‹ฑํ•ด authority ํ‚ค์ฒด์ธ๋„ ๊ฐฑ์‹ ํ•œ๋‹ค.
// ์„œ๋ฒ„๊ฐ€ DB์—์„œ role์„ ๋ณ€๊ฒฝํ•œ ๊ฒฝ์šฐ, ์ƒˆ๋กœ ๋ฐœ๊ธ‰๋œ ํ† ํฐ์—๋Š” ๋ณ€๊ฒฝ๋œ role์ด ๋‹ด๊ธฐ๋ฏ€๋กœ
// ์ด ์‹œ์ ์— authority๋ฅผ ๋ฎ์–ด์จ์•ผ ์•ฑ์ด ์ตœ์‹  ๊ถŒํ•œ์„ ๋ฐ˜์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
if let payload = newAccessToken.split(separator: ".").dropFirst().first {
let base64url = String(payload)
let base64 = base64url
.replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
let paddedPayload = base64 + String(repeating: "=", count: (4 - base64.count % 4) % 4)
if let data = Data(base64Encoded: paddedPayload),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let role = json["role"] as? String {
keychain.create(key: Const.KeyChainKey.authority, token: role)
}
}
Comment thread
minsun-0209 marked this conversation as resolved.

if accessTokenUpdated && refreshTokenUpdated {
print("keychain update success")
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public class AdminMainViewController: BaseViewController, UICollectionViewDataSo
super.viewWillAppear(animated)
isVisible = true
isClockOn = UserDefaults.standard.bool(forKey: "isClockOn")
fetchData()
syncRoleAndFetch()
setupNavigationBar()
}

Expand Down Expand Up @@ -240,6 +240,35 @@ public class AdminMainViewController: BaseViewController, UICollectionViewDataSo
}
}

/// ์•ฑ ์žฌ์ง„์ž… ๋˜๋Š” ํ™”๋ฉด ์ง„์ž… ์‹œ ์ตœ์‹  role์„ ์„œ๋ฒ„์—์„œ ํ™•์ธํ•ด ํ™”๋ฉด์„ ์ „ํ™˜ํ•œ๋‹ค.
/// 1. reissue๋กœ ํ† ํฐ์„ ๊ฐฑ์‹  (์ƒˆ JWT์— ์ตœ์‹  role ํฌํ•จ)
/// 2. /member/myrole๋กœ ํ˜„์žฌ role ํ™•์ธ
/// 3. role์ด ROLE_STUDENT๋กœ ๋ฐ”๋€Œ์—ˆ์œผ๋ฉด MainViewController๋กœ ์ „ํ™˜
private func syncRoleAndFetch() {
viewModel.gomsRefreshToken.tokenReissuance { [weak self] success in
guard let self else { return }
if success {
self.viewModel.getProfile { [weak self] authority in
guard let self else { return }
DispatchQueue.main.async {
guard self.isVisible else { return }
if authority == "ROLE_STUDENT" {
let mainVC = MainViewController()
self.navigationController?.setViewControllers([mainVC], animated: false)
return
}
self.fetchData()
}
Comment thread
minsun-0209 marked this conversation as resolved.
Comment thread
Copilot marked this conversation as resolved.
}
} else {
DispatchQueue.main.async { [weak self] in
guard let self, self.isVisible else { return }
self.fetchData()
}
}
}
}

private func fetchData() {
let group = DispatchGroup()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,7 @@ public final class MainViewController: BaseViewController, UICollectionViewDataS
super.viewWillAppear(animated)
isVisible = true
isClockOn = UserDefaults.standard.bool(forKey: "isClockOn")

mainViewModel.getLateList { [weak self] in
self?.mainViewModel.getOutingList { [weak self] in
self?.setup()
}
}

fetchData()

syncRoleAndFetch()
Comment thread
minsun-0209 marked this conversation as resolved.
self.navigationController?.navigationBar.prefersLargeTitles = false
self.navigationItem.hidesBackButton = true
self.navigationController?.setNavigationBarHidden(true, animated: false)
Expand Down Expand Up @@ -409,6 +401,32 @@ public final class MainViewController: BaseViewController, UICollectionViewDataS
}
}

/// ํ™”๋ฉด ์ง„์ž… ์‹œ ํ† ํฐ์„ ๊ฐฑ์‹ ํ•˜๊ณ  ์ตœ์‹  role์„ ํ™•์ธํ•ด ํ•„์š”ํ•˜๋ฉด ํ™”๋ฉด์„ ์ „ํ™˜ํ•œ๋‹ค.
private func syncRoleAndFetch() {
mainViewModel.gomsRefreshToken.tokenReissuance { [weak self] success in
guard let self else { return }
if success {
self.mainViewModel.getProfile { [weak self] authority in
guard let self else { return }
Comment thread
minsun-0209 marked this conversation as resolved.
DispatchQueue.main.async {
guard self.isVisible else { return }
if authority == "ROLE_STUDENT_COUNCIL" {
let adminVC = AdminMainViewController()
self.navigationController?.setViewControllers([adminVC], animated: false)
return
}
self.fetchData()
}
}
} else {
DispatchQueue.main.async { [weak self] in
guard let self, self.isVisible else { return }
self.fetchData()
}
}
}
}

private func fetchData() {
let group = DispatchGroup()

Expand Down
Loading