Skip to content

Instantly share code, notes, and snippets.

@likil33
Created June 27, 2024 08:33
Show Gist options
  • Select an option

  • Save likil33/f60c858c1068c8e582c2226f2c6fb4b8 to your computer and use it in GitHub Desktop.

Select an option

Save likil33/f60c858c1068c8e582c2226f2c6fb4b8 to your computer and use it in GitHub Desktop.
Okta-customLogin-refreshToken
// 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)
}
}
@likil33
Copy link
Author

likil33 commented Jun 27, 2024

Okta login - refresh toke

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment