-
Notifications
You must be signed in to change notification settings - Fork 0
[TDH-31] 로그인 api 및 토큰 저장 처리부 구현 #12
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: dev
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| // | ||
| // DCInterceptor.swift | ||
| // DiningCoach | ||
| // | ||
| // Created by 이송미 on 2023/07/10. | ||
| // | ||
|
|
||
| import Foundation | ||
| import Alamofire | ||
|
|
||
| final class DCInterceptor: RequestInterceptor { | ||
| func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) { | ||
| var urlRequest = urlRequest | ||
| urlRequest.headers.add(.accept("application/json")) | ||
| urlRequest.headers.add(.contentType("application/json")) | ||
|
|
||
| completion(.success(urlRequest)) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| // | ||
| // LoginAPI.swift | ||
| // DiningCoach | ||
| // | ||
| // Created by 이송미 on 2023/07/10. | ||
| // | ||
|
|
||
| import Foundation | ||
| import Alamofire | ||
|
|
||
| final public class LoginApi { | ||
| static let shared = LoginApi() | ||
| let loginSession: Session | ||
|
|
||
| init() { | ||
| let apiConfiguration = URLSessionConfiguration.default | ||
| apiConfiguration.tlsMinimumSupportedProtocolVersion = .TLSv12 | ||
| loginSession = Session(configuration: apiConfiguration, interceptor: DCInterceptor()) | ||
| } | ||
|
|
||
| } | ||
|
|
||
| extension LoginApi { | ||
| func loginWithSso(platformType: PlatformType, userAgent: String, accessToken: String, completion: @escaping (SsoResponse?, Error?) -> Void) { | ||
| loginSession.request(Urls.compose(path: Paths.requestSso), method: .post, parameters: ["platformType": platformType, "userAgent": userAgent, "accessToken": accessToken]) | ||
| .responseDecodable(of: SsoResponse.self) { [weak self] response in | ||
| self?.handleResponse(response: response, completion: completion) | ||
| } | ||
| } | ||
|
|
||
| func loginWithEmail(email: String, password: String, completion: @escaping (SsoResponse?, Error?) -> Void) { | ||
| loginSession.request(Urls.compose(path: Paths.login), method: .post, parameters: ["email": email, "password": password]) | ||
| .responseDecodable(of: SsoResponse.self) { [weak self] response in | ||
| self?.handleResponse(response: response, completion: completion) | ||
| } | ||
| } | ||
|
|
||
| func register(email: String, password: String, completion: @escaping (SsoResponse?, Error?) -> Void) { | ||
| loginSession.request(Urls.compose(path: Paths.register), method: .post, parameters: ["email": email, "password": password]) | ||
| .responseDecodable(of: SsoResponse.self) { [weak self] response in | ||
| self?.handleResponse(response: response, completion: completion) | ||
| } | ||
| } | ||
|
|
||
| func refresh(userId: String, refreshToken: String, completion: @escaping (SsoResponse? , Error?) -> Void) { | ||
| loginSession.request(Urls.compose(path: Paths.refresh), method: .post, parameters: ["userId": userId, "refreshToken": refreshToken]) | ||
| .responseDecodable(of: SsoResponse.self) { [weak self] response in | ||
| self?.handleResponse(response: response, completion: completion) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| extension LoginApi { | ||
| private func handleResponse(response: DataResponse<SsoResponse, AFError>, completion: @escaping (SsoResponse?, Error?) -> Void) { | ||
| switch response.result { | ||
| case .success(let result): | ||
| completion(result, nil) | ||
| case .failure(let error): | ||
| completion(nil, error) | ||
| } | ||
|
Comment on lines
+55
to
+60
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @songmilee |
||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // | ||
| // Login.swift | ||
| // DiningCoach | ||
| // | ||
| // Created by 이송미 on 2023/07/05. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public enum PlatformType: String, Codable { | ||
| case kakao, google, apple | ||
| } | ||
|
|
||
| struct SsoResponse: Codable { | ||
| let userId: Int64 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| let newUser: Bool? | ||
| let accessToken: String | ||
| let refreshToken: String | ||
| } | ||
|
|
||
| struct User: Codable { | ||
| let id: Int64 | ||
| let userName: String | ||
| let firstName: String | ||
| let email: String | ||
| let password: String | ||
| let phone: String | ||
| let userStatus: Int32 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // | ||
| // Urls.swift | ||
| // DiningCoach | ||
| // | ||
| // Created by 이송미 on 2023/07/05. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| public struct Hosts { | ||
| public static let shared = Hosts() | ||
|
|
||
| public let base = "virtserver.swaggerhub.com/DININGCOACHTEAM/DiningCoach_API_v1/1.0.0" // "diningcoach.org" | ||
| } | ||
|
|
||
| public struct Paths { | ||
| public static let requestSso = "/api/v1/auth/sso" | ||
| public static let login = "/api/v1/auth/login" | ||
| public static let register = "/api/v1/auth/register" | ||
| public static let refresh = "/api/v1/auth/refresh" | ||
| } | ||
|
|
||
| public struct Urls { | ||
| public static func compose(_ host: String = Hosts.shared.base, path: String) -> String { | ||
| return "https://\(host)\(path)" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // | ||
| // TokenManager.swift | ||
| // DiningCoach | ||
| // | ||
| // Created by 이송미 on 2023/07/12. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
|
|
||
| final class TokenManager { | ||
| public static let shared = TokenManager() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @songmilee |
||
| var token: SsoResponse? = nil | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @songmilee final class TokenManager {
var token: SsoResponse? {
get {
guard let tokenData = UserDefaults.standard.data(forKey: key) else { return nil }
return try? JSONDecoder().decode(SsoResponse.self, from: tokenData)
}
set {
guard let data = try? JSONEncoder().encode(token) else { return }
UserDefaults.standard.set(data, forKey: key)
}
}
}이런 형태의 computed property는 property wrapper를 사용하면 더 간단하게 사용할 수도 있습니다. final class TokenManager {
@SSOResponse
var token: SsoResponse?
} |
||
|
|
||
| let key = "com.diningcoach.token" | ||
|
|
||
| init() { | ||
| if let tokenData = UserDefaults.standard.data(forKey: key) { | ||
| let token = try? JSONDecoder().decode(SsoResponse.self, from: tokenData) | ||
| self.token = token | ||
| } | ||
|
Comment on lines
+18
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @songmilee init() {
guard let tokenData = UserDefaults.standard.data(forKey: key) else { return }
token = try? JSONDecoder().decode(SsoResponse.self, from: tokenData)
} |
||
| } | ||
|
|
||
| func setToken(token: SsoResponse) { | ||
| if let data = try? JSONEncoder().encode(token) { | ||
| UserDefaults.standard.set(data, forKey: key) | ||
| UserDefaults.standard.synchronize() | ||
|
|
||
| self.token = token | ||
| } | ||
|
Comment on lines
+25
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @songmilee |
||
| } | ||
|
|
||
| func getToken() -> SsoResponse? { | ||
| return token | ||
| } | ||
|
|
||
| func deleteToken() { | ||
| UserDefaults.standard.removeObject(forKey: key) | ||
| self.token = nil | ||
| } | ||
| } | ||
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.
@songmilee
Method 호출부 코드가 너무 길어지면 parameter를 기준으로 적절하게 개행하시면 가독성이 더 높아질 것입니다