Skip to content
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

[FIX] #253 - 카카오톡 로그인 post 서버 통신 시, oauthToken을 사용하도록 변경 #254

Merged
merged 10 commits into from
Dec 29, 2021
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
2 changes: 1 addition & 1 deletion NADA-iOS-forRelease/Resouces/Constants/Const.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
import Foundation

struct Const {

static let headerToken: String = UserDefaults.standard.string(forKey: Const.UserDefaultsKey.accessToken) ?? ""
}
3 changes: 2 additions & 1 deletion NADA-iOS-forRelease/Resouces/Constants/Header.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import Foundation

extension Const {

struct Header {
static var bearerHeader = ["Authorization": "Bearer " + UserDefaults.standard.string(forKey: Const.UserDefaultsKey.accessToken)!]

static var basicHeader = ["Content-Type": "application/json",
"Authorization": "Bearer " + UserDefaults.standard.string(forKey: Const.UserDefaultsKey.accessToken)!]
"Authorization": "Bearer " + headerToken]
}
}
2 changes: 2 additions & 0 deletions NADA-iOS-forRelease/Resouces/Constants/UserDefaults.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ extension Const {
static let isFirstCard = "isFirstCard"
static let isOnboarding = "isOnboarding"
static let firstCardID = "firstCardID"
static let isAppleLogin = "isAppleLogin"
static let isKakaoLogin = "isKakaoLogin"
}
}
76 changes: 50 additions & 26 deletions NADA-iOS-forRelease/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,66 @@

import UIKit
import KakaoSDKCommon
import KakaoSDKAuth
import KakaoSDKUser
import AuthenticationServices

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

// var isLogin = false
var isLogin = false

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// removeKeychainAtFirstLaunch()

KakaoSDKCommon.initSDK(appKey: "5b8dd8cc878344bb7532eeca4365a4aa")
let acToken = UserDefaults.standard.string(forKey: Const.UserDefaultsKey.accessToken)

// let appleIDProvider = ASAuthorizationAppleIDProvider()
// appleIDProvider.getCredentialState(forUserID: Const.UserDefaults.userID) { (credentialState, error) in
// switch credentialState {
// case .authorized:
// print("해당 ID는 연동되어있습니다.")
// self.isLogin = true
// case .revoked:
// print("해당 ID는 연동되어있지않습니다.")
// self.isLogin = false
// case .notFound:
// print("해당 ID를 찾을 수 없습니다.")
// self.isLogin = false
// default:
// break
// }
// }

// NotificationCenter.default.addObserver(forName: ASAuthorizationAppleIDProvider.credentialRevokedNotification, object: nil, queue: nil) { (Notification) in
// print("Revoked Notification")
// self.isLogin = false
// }
if acToken != nil {
if UserDefaults.standard.bool(forKey: Const.UserDefaultsKey.isAppleLogin) {
// 애플 로그인으로 연동되어 있을 때, -> 애플 ID와의 연동상태 확인 로직
let appleIDProvider = ASAuthorizationAppleIDProvider()
appleIDProvider.getCredentialState(forUserID: UserDefaults.standard.string(forKey: Const.UserDefaultsKey.userID) ?? "") { (credentialState, error) in
switch credentialState {
case .authorized:
print("해당 ID는 연동되어있습니다.")
self.isLogin = true
case .revoked:
print("해당 ID는 연동되어있지않습니다.")
self.isLogin = false
case .notFound:
print("해당 ID를 찾을 수 없습니다.")
self.isLogin = false
default:
break
}
}
} else {
if AuthApi.hasToken() { // 유효한 토큰 존재
UserApi.shared.accessTokenInfo { (_, error) in
if let error = error {
if let sdkError = error as? SdkError, sdkError.isInvalidTokenError() == true {
self.isLogin = false
}
} else {
// 토큰 유효성 체크 성공(필요 시 토큰 갱신됨)
self.isLogin = true
}
}
} else {
// 카카오 토큰 없음 -> 로그인 필요
self.isLogin = false
}
}
} else {
self.isLogin = false // acToken 값이 nil일 때 -> 로그인 뷰로
}

// 앱 실행 중 애플 ID 강제로 연결 취소 시
NotificationCenter.default.addObserver(forName: ASAuthorizationAppleIDProvider.credentialRevokedNotification, object: nil, queue: nil) { (Notification) in
print("Revoked Notification")
self.isLogin = false
}

return true
}
Expand All @@ -57,7 +84,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}


}

Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ extension GroupService: TargetType {
return Const.Header.bearerHeader
case .groupAdd, .groupEdit, .cardAddInGroup, .changeCardGroup:
return Const.Header.bearerHeader
case .groupReset(let token):
return ["Content-Type": "application/json", "Authorization": "Bearer " + token]
case .groupReset:
return Const.Header.basicHeader
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,8 @@ extension UserSevice: TargetType {
return Const.Header.bearerHeader
case .userSignUp, .userSocialSignUp, .userTokenReissue:
return ["Content-Type": "application/json"]
case .userDelete(let token):
return ["Content-Type": "application/json", "Authorization": "Bearer " + token]
case .userLogout(let token):
return ["Content-Type": "application/json", "Authorization": "Bearer " + token]
case .userDelete, .userLogout:
return Const.Header.basicHeader
}
}
}
54 changes: 1 addition & 53 deletions NADA-iOS-forRelease/Sources/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window.overrideUserInterfaceStyle = .light
}
}

// 스플래시 지연시간동안 자동 로그인 작업처리
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
let acToken = self.defaults.string(forKey: Const.UserDefaultsKey.accessToken)
let rfToken = self.defaults.string(forKey: Const.UserDefaultsKey.refreshToken)

self.postUserTokenReissue(request: UserTokenReissueRequset(accessToken: acToken ?? "", refreshToken: rfToken ?? ""))
}

}

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
Expand All @@ -54,53 +47,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
}
}

// MARK: - Network

func postUserTokenReissue(request: UserTokenReissueRequset) {
UserAPI.shared.userTokenReissue(request: request) { response in
switch response {
case .success:
print("postUserTokenReissue - Success")

var rootViewController = UIStoryboard(name: Const.Storyboard.Name.login, bundle: nil)
.instantiateViewController(identifier: Const.ViewController.Identifier.loginViewController)

if self.defaults.string(forKey: Const.UserDefaultsKey.accessToken) != "" {
rootViewController = UIStoryboard(name: Const.Storyboard.Name.tabBar, bundle: nil).instantiateViewController(withIdentifier: Const.ViewController.Identifier.tabBarViewController)
} else {
rootViewController = UIStoryboard(name: Const.Storyboard.Name.login, bundle: nil)
.instantiateViewController(identifier: Const.ViewController.Identifier.loginViewController)
}
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
case .requestErr(let message):
print("postUserTokenReissue - requestErr: \(message)")

self.presentToLoginViewController()
case .pathErr:
print("postUserTokenReissue - pathErr")
case .serverErr:
print("postUserTokenReissue - serverErr")
case .networkFail:
print("postUserTokenReissue - networkFail")
}
}
}

// MARK: - Methods

private func presentToLoginViewController() {
if UserDefaults.standard.object(forKey: Const.UserDefaultsKey.isOnboarding) != nil {
let rootViewController = UIStoryboard(name: Const.Storyboard.Name.login, bundle: nil).instantiateViewController(identifier: Const.ViewController.Identifier.loginViewController)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
} else {
let rootViewController = UIStoryboard(name: Const.Storyboard.Name.onboarding, bundle: nil).instantiateViewController(identifier: Const.ViewController.Identifier.onboardingViewController)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()
}
}

func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ class LoginViewController: UIViewController {
])

let authorizationButton = ASAuthorizationAppleIDButton(type: .signIn, style: .black)
// let authorizationButton = UIButton()
// authorizationButton.setImage(UIImage(named: "appleLogin"), for: .normal)
authorizationButton.addTarget(self, action: #selector(appleSignInButtonPress), for: .touchUpInside)
loginProviderStackView.addSubview(authorizationButton)

Expand Down Expand Up @@ -76,24 +74,16 @@ class LoginViewController: UIViewController {
// 카카오 로그인 버튼 클릭 시
@objc
func kakaoSignInButtonPress() {
if AuthApi.hasToken() { // 유효한 토큰 존재
UserApi.shared.accessTokenInfo { (_, error) in
if let error = error {
if let sdkError = error as? SdkError, sdkError.isInvalidTokenError() == true {
// 로그인 필요
self.signUp()
}
} else {
// 토큰 유효성 체크 성공(필요 시 토큰 갱신됨)
self.signUp()
}
}
// 카카오톡 설치 여부 확인
if UserApi.isKakaoTalkLoginAvailable() {
// 카카오톡 로그인. api 호출 결과를 클로저로 전달.
loginWithApp()
} else {
// 카카오 토큰 없음 -> 로그인 필요
self.signUp()
// 만약, 카카오톡이 깔려있지 않을 경우에는 웹 브라우저로 카카오 로그인함.
loginWithWeb()
}
}

// 애플 로그인 버튼 클릭 시
@objc
func appleSignInButtonPress() {
Expand All @@ -112,18 +102,20 @@ class LoginViewController: UIViewController {
// MARK: - KakaoSignIn
extension LoginViewController {
func loginWithApp() {
UserApi.shared.loginWithKakaoTalk {(_, error) in
UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in
if let error = error {
print(error)
} else {
print("loginWithKakaoTalk() success.")

UserApi.shared.me {(user, error) in
UserApi.shared.me {(_, error) in
if let error = error {
print(error)
} else {
if let email = user?.kakaoAccount?.email {
self.postUserSignUpWithAPI(request: email)
if let token = oauthToken?.accessToken {
self.postUserSignUpWithAPI(request: token)
UserDefaults.standard.set(false, forKey: Const.UserDefaultsKey.isAppleLogin)
UserDefaults.standard.set(true, forKey: Const.UserDefaultsKey.isKakaoLogin)
Comment on lines +111 to +118
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mini-min 지금 뒤늦게 또 보고있는데 UserAPI.shared.me 는 사용자 정보를 가져오는거라서 우리는 굳이 안가져오니까 이 코드는 사용하지 않아도 될거 같아요....!
하지만 있어도 문제없는 코드니까 민재도 알고 넘어가면 될거 같네요!

}
}
}
Expand All @@ -133,18 +125,20 @@ extension LoginViewController {
}

func loginWithWeb() {
UserApi.shared.loginWithKakaoAccount {(_, error) in
UserApi.shared.loginWithKakaoAccount {(oauthToken, error) in
if let error = error {
print(error)
} else {
print("loginWithKakaoAccount() success.")

UserApi.shared.me {(user, error) in
UserApi.shared.me {(_, error) in
if let error = error {
print(error)
} else {
if let email = user?.kakaoAccount?.email {
self.postUserSignUpWithAPI(request: email)
if let token = oauthToken?.accessToken {
self.postUserSignUpWithAPI(request: token)
UserDefaults.standard.set(false, forKey: Const.UserDefaultsKey.isAppleLogin)
UserDefaults.standard.set(true, forKey: Const.UserDefaultsKey.isKakaoLogin)
Comment on lines +138 to +141
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loginWithApp 메서드에서도 token 을 다루어야 할거 같아요! 그리고 userDefaults 에 저장해주세요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 감사합니다 급해서 ^__^
userDefaults에는 통신하고 토큰값이랑 일괄적으로 아이디도 담고있습니다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗! 넵 수고했어요!

}
}
}
Expand Down Expand Up @@ -174,17 +168,13 @@ extension LoginViewController: ASAuthorizationControllerDelegate, ASAuthorizatio
// Apple ID 연동 성공 시
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
switch authorization.credential {
// Apple ID
// Apple ID
case let appleIDCredential as ASAuthorizationAppleIDCredential:

let userIdentifier = appleIDCredential.user
// let fullName = appleIDCredential.fullName
// let email = appleIDCredential.email

// print("User ID : \(userIdentifier)")
// print("User Email : \(email ?? "")")
// print("User Name : \((fullName?.givenName ?? "") + (fullName?.familyName ?? ""))")
postUserSignUpWithAPI(request: userIdentifier)
UserDefaults.standard.set(true, forKey: Const.UserDefaultsKey.isAppleLogin)
UserDefaults.standard.set(false, forKey: Const.UserDefaultsKey.isKakaoLogin)

default:
break
Expand All @@ -206,10 +196,8 @@ extension LoginViewController {
print("postUserSignUpWithAPI - success")
if let userData = loginData as? UserWithTokenRequest {
UserDefaults.standard.set(userData.user.userID, forKey: Const.UserDefaultsKey.userID)
let tokenData = userData.user.token
UserDefaults.standard.set(tokenData.accessToken, forKey: Const.UserDefaultsKey.accessToken)
UserDefaults.standard.set(tokenData.refreshToken, forKey: Const.UserDefaultsKey.refreshToken)

UserDefaults.standard.set(userData.user.token.accessToken, forKey: Const.UserDefaultsKey.accessToken)
UserDefaults.standard.set(userData.user.token.refreshToken, forKey: Const.UserDefaultsKey.refreshToken)
self.presentToMain()
}
case .requestErr(let message):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ extension MoreViewController {
if let acToken = UserDefaults.standard.string(forKey: Const.UserDefaultsKey.accessToken) {
self.logoutUserWithAPI(token: acToken)
self.defaults.removeObject(forKey: Const.UserDefaultsKey.accessToken)
self.defaults.removeObject(forKey: Const.UserDefaultsKey.refreshToken)
self.defaults.removeObject(forKey: Const.UserDefaultsKey.darkModeState)
let nextVC = UIStoryboard(name: Const.Storyboard.Name.login, bundle: nil).instantiateViewController(withIdentifier: Const.ViewController.Identifier.loginViewController)
nextVC.modalPresentationStyle = .overFullScreen
Expand Down Expand Up @@ -147,6 +148,7 @@ extension MoreViewController {
if let acToken = UserDefaults.standard.string(forKey: Const.UserDefaultsKey.accessToken) {
self.deleteUserWithAPI(token: acToken)
self.defaults.removeObject(forKey: Const.UserDefaultsKey.accessToken)
self.defaults.removeObject(forKey: Const.UserDefaultsKey.refreshToken)
self.defaults.removeObject(forKey: Const.UserDefaultsKey.darkModeState)
let nextVC = UIStoryboard(name: Const.Storyboard.Name.login, bundle: nil).instantiateViewController(withIdentifier: Const.ViewController.Identifier.loginViewController)
nextVC.modalPresentationStyle = .overFullScreen
Expand Down
Loading