Customizing requests from the OIDC module on iOS
PingOne Advanced Identity Cloud PingAM PingOne iOS
All modules in the Orchestration SDK for iOS use an HTTP client abstraction provided by the PingNetwork module to make network requests.
You can use this HTTP client to create interceptors, that can modify requests before they’re sent, or inspect responses after they’re received.
For example, you can add or customize:
-
Query parameters
-
Headers
-
Cookies
-
Body data
Step 1. Creating an HTTP client
To customize network requests, initialize and configure an HttpClient instance:
import PingNetwork
let customHttpClient = HttpClient.createClient { config in
// Optional: Configure timeout (default: 15 seconds)
config.timeout = 30.0
// Optional: Configure logging (default: LogManager.logger)
config.logger = LogManager.warning
}
Use the following properties to configure the HTTP client:
- timeout
-
The number of seconds to wait before each request times out.
Default is
15seconds. - logger
-
The logger that
HttpClientuses for output.Available options are:
Value Description LogManager.standardOutputs all log messages to the console.
LogManager.warningOutputs only warning and error log messages to the console.
LogManager.nonePrevents all log messages.
LogManager.loggerUse whichever logger is already configured in the application.
Learn more in Configuring logging on iOS.
Default is
LogManager.logger.
Step 2. Adding interceptors to the HTTP client
Add custom interceptors to the HTTP client to modify requests before they’re sent or inspect responses after they’re received.
Adding request interceptors
To add an interceptor that applies to all outgoing requests from a module, use the onRequest method.
To customize the requests, pass in your own values for headers, query parameters, cookies, or body parameters.
-
Headers
-
Query parameters
-
Body data
let customHttpClient = HttpClient.createClient { config in
// Add authentication token to all requests
config.onRequest { request in
request.setHeader(name: "Authorization", value: "Bearer \(token)")
}
// Add custom user agent
config.onRequest { request in
request.setHeader(name: "User-Agent", value: "MyApp/1.0")
}
}
let customHttpClient = HttpClient.createClient { config in
// Add custom query parameters
config.onRequest { request in
request.setParameter(name: "lang", value: "en-UK")
request.setParameter(name: "brand", value: "example.co.uk")
}
}
let customHttpClient = HttpClient.createClient { config in
// Add JSON body data to a POST request
config.onRequest { request in
request.post(json: [
"name": "John Doe",
"email": "john@example.com"
])
}
// Add JSON body data to a PUT request
config.onRequest { request in
request.put(json: [
"name": "Updated Name",
"email": "updated@example.com"
])
}
// Add form-encoded body data to a POST request
config.onRequest { request in
request.form(parameters: [
"name": "John Doe",
"email": "john@example.com"
])
}
}
Adding response interceptors
To add an interceptor that can inspect all incoming responses to a module, use the onResponse method.
To inspect the response, capture the values of the incoming headers, cookies, body parameters, and HTTP response status.
You can also capture the original request object that triggered the response, which can be useful for auditing or debugging purposes.
-
HTTP Status
-
Headers
-
Body data
-
Original request
let customHttpClient = HttpClient.createClient { config in
// Use convenience methods on HTTP status code of a response
config.onResponse { response in
if response.status.isSuccess() {
// 2xx status code
} else if response.status.isRedirect() {
// 3xx status code
} else if response.status.isClientError() {
// 4xx status code
} else if response.status.isServerError() {
// 5xx status code
}
}
}
let customHttpClient = HttpClient.createClient { config in
// Get all headers
config.onResponse { response in
let allHeaders = response.headers
}
// Get individual header
config.onResponse { response in
if let contentType = response.getHeader(name: "Content-Type") {
print("Content-Type: \(contentType)")
}
}
}
let customHttpClient = HttpClient.createClient { config in
// Get body data as a string
config.onResponse { response in
let bodyString = response.bodyAsString()
}
// Get body as raw data type
config.onResponse { response in
if let bodyData = response.body {
let json = try? JSONSerialization.jsonObject(with: bodyData)
}
}
}
let customHttpClient = HttpClient.createClient { config in
// Capture the original outgoing request
config.onResponse { response in
let originalRequest = response.request
}
}
Step 3. Configuring the OIDC web client to use an HTTP client
Pass the name of your custom HTTP client to the createOidcWebClient method in the httpClient parameter:
oidc modulepublic let oidcLogin = OidcWebClient.createOidcWebClient { config in
// Custom HTTP client
config.httpClient = customHttpClient
// Other configuration
config.module(PingOidc.OidcModule.config) { oidcValue in
oidcValue.discoveryEndpoint = "https://auth.pingone.ca/3072206d-c6ce-ch15-m0nd-f87e972c7cc3/as/.well-known/openid-configuration"
oidcValue.clientId = "6c7eb89a-66e9-ab12-cd34-eeaf795650b2"
oidcValue.redirectUri = "https://demo.example.com/oauth2redirect"
oidcValue.scopes = ["openid", "email", "address", "profile", "phone"]
}
}