Created
June 27, 2024 08:33
-
-
Save likil33/f60c858c1068c8e582c2226f2c6fb4b8 to your computer and use it in GitHub Desktop.
Okta-customLogin-refreshToken
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 1 - (At webservice - refreshTOken) | |
| OktaAuthManager.shared.renewTokens { stateManager, error in | |
| if let error = error { | |
| print("Renew token error: \(error)") | |
| return | |
| } | |
| // Successfully renewed token | |
| if let newAccessToken = stateManager?.accessToken { | |
| print("New Access Token: \(newAccessToken)") | |
| UserDefaults.standard.oktaAccessToken = newAccessToken | |
| } | |
| } | |
| // 2 At Login - request email and password - custome screen | |
| self.startLoading() | |
| OktaAuthManager.shared.signInOktaWithEmailPassword(userName: userName, password: password) { status in | |
| self.stopLoading() | |
| if status { | |
| handler(status) | |
| } | |
| else { | |
| AppAlertView.shared.displayAlertwithOK("Alert!", "Okta Error") { flag in | |
| } | |
| } | |
| } | |
| // | |
| //Helper class | |
| import Foundation | |
| import OktaOidc | |
| import OktaAuthSdk | |
| enum OktaDetails:String { | |
| case urlStr = "https://dev-{1234567}.okta.com" | |
| } | |
| class OktaAuthManager { | |
| static let shared = OktaAuthManager() | |
| private var oktaOidc: OktaOidc | |
| private var stateManager: OktaOidcStateManager? | |
| private init() { | |
| do { | |
| let config = try OktaOidcConfig(fromPlist: "Okta") | |
| oktaOidc = try OktaOidc(configuration: config) | |
| retrieveStateManager() | |
| } catch { | |
| fatalError("Failed to initialize OktaOidc: \(error.localizedDescription)") | |
| } | |
| } | |
| func retrieveStateManager() { | |
| if let stateManager = OktaOidcStateManager.readFromSecureStorage(for: oktaOidc.configuration) { | |
| self.stateManager = stateManager | |
| } | |
| } | |
| // func signIn(username: String, password: String, completion: @escaping (Result<Void, Error>) -> Void) { | |
| // do { | |
| // let tokenResponse = try oktaOidc.authenticate(withSessionToken: username, callback: password) | |
| // if let stateManager = tokenResponse.stateManager { | |
| // self.stateManager = stateManager | |
| // do { | |
| // try stateManager.writeToSecureStorage() | |
| // completion(.success(())) | |
| // } catch { | |
| // completion(.failure(error)) | |
| // } | |
| // } else if let error = tokenResponse.error { | |
| // completion(.failure(error)) | |
| // } | |
| // } catch { | |
| // completion(.failure(error)) | |
| // } | |
| // } | |
| func signInOktaWithEmailPassword(userName:String, password:String, handler:@escaping(_ status:Bool)-> Void) { | |
| // var urlString = "https://dev-6648617.okta.com" | |
| var urlString = OktaDetails.urlStr.rawValue | |
| let successBlock: (OktaAuthStatus) -> Void = { [weak self] status in | |
| if let statuss = status as? OktaAuthStatusSuccess { | |
| let oktaDetails = statuss.user?.profile | |
| var userInfo = [String:Any]() | |
| userInfo["name"] = "\(oktaDetails?.lastName ?? "user") \(oktaDetails?.firstName ?? "Unknown")" | |
| userInfo["email"] = "\(oktaDetails?.login ?? "email@mail.com")" | |
| UserDefaults.standard.loginUserInfo = userInfo | |
| // handler(statuss) | |
| self?.setupOkta(status: statuss) { flag in | |
| handler(flag) | |
| } | |
| } | |
| } | |
| let errorBlock: (OktaError) -> Void = { [weak self] error in | |
| print(error) | |
| handler(false) | |
| AppAlertView.shared.showAlert("Alert!", error.description) | |
| } | |
| OktaAuthSdk.authenticate(with: URL(string: urlString)!, | |
| username: userName, | |
| password: password, | |
| onStatusChange: successBlock, | |
| onError: errorBlock) | |
| } | |
| func setupOkta(status: OktaAuthStatusSuccess, handler:@escaping(_ status:Bool)-> Void) { | |
| DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { | |
| let oidcClient = try? OktaOidc() | |
| oidcClient?.authenticate(withSessionToken: status.sessionToken!, callback: { [weak self] stateManager, error in | |
| if let stateManager = stateManager { | |
| if let accessToken = stateManager.accessToken { | |
| print("accessToken: \n \(accessToken)") | |
| UserDefaults.standard.oktaAccessToken = accessToken | |
| if let refreshToken = stateManager.refreshToken { | |
| print(refreshToken) | |
| // UserDefaults.standard.oktaRefreshToken = refreshToken | |
| } | |
| self?.stateManager = stateManager | |
| stateManager.writeToSecureStorage() | |
| handler(true) | |
| } | |
| else { | |
| handler(false) | |
| } | |
| } | |
| else { | |
| handler(false) | |
| } | |
| }) | |
| } | |
| } | |
| func signOut(completion: @escaping (Error?) -> Void) { | |
| guard let stateManager = stateManager else { | |
| completion(nil) | |
| return | |
| } | |
| stateManager.revoke(stateManager.accessToken) { _, error in | |
| if let error = error { | |
| completion(error) | |
| return | |
| } | |
| stateManager.revoke(stateManager.refreshToken) { _, error in | |
| if let error = error { | |
| completion(error) | |
| return | |
| } | |
| do { | |
| try stateManager.removeFromSecureStorage() | |
| self.stateManager = nil | |
| self.clearOktaCookies(completion: completion) | |
| } catch { | |
| completion(error) | |
| } | |
| } | |
| } | |
| } | |
| func renewTokens(completion: @escaping (OktaOidcStateManager?, Error?) -> Void) { | |
| guard let stateManager = OktaOidcStateManager.readFromSecureStorage(for: oktaOidc.configuration) else { | |
| completion(nil,nil) | |
| return | |
| } | |
| stateManager.renew { [weak self] newStateManager, error in | |
| guard let self = self else { return } | |
| if let newStateManager = newStateManager { | |
| self.stateManager = newStateManager | |
| newStateManager.writeToSecureStorage() | |
| completion(newStateManager, nil) | |
| } else if let error = error { | |
| completion(nil, error) | |
| } | |
| } | |
| } | |
| func getAccessToken() -> String? { | |
| return stateManager?.accessToken | |
| } | |
| private func clearOktaCookies(completion: @escaping (Error?) -> Void) { | |
| let cookieStore = HTTPCookieStorage.shared | |
| if let cookies = cookieStore.cookies { | |
| for cookie in cookies { | |
| if cookie.domain.contains("okta") { | |
| cookieStore.deleteCookie(cookie) | |
| } | |
| } | |
| } | |
| completion(nil) | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Okta login - refresh toke