Single Sign-on for iOS
Enable your registered users to access members-only functionalities using your app's existing user management system.
There are two types of SSO available: Standard and third-party single sign-on. Please contact your OpenWeb PSM if you are unsure which implementation method applies to you.
Implementation Options
Standard
- Authenticate a user with your backend user management system.
func login(username: String, password: String) { [weak self] in
guard let self = self else { return }
MyAuthenticationProvider.login(
with: username,
password: password) { [weak self] result in
guard let self = self else { return }
switch result {
case .success(_):
self.authenticateWithSpotIm()
case .failure(let error):
handleLoginError()
}
}
}
- Call
startSSO
function and getcodeA
.
func authenticateWithSpotIm() {
SpotIm.startSSO { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let ssoResponse):
guard let codeA = ssoResponse.codeA else {
//Handle error
return
}
self.getCodeB(codeA: response?.codeA)
case .failure(let error):
//Handle error
break
}
}
}
- Send the
codeA
and all needed information to your backend system to getcodeB
:
- From your backend system, make a
GET /sso/v1/register-user
call to OpenWeb. The API call must include your secret access token (access_token
), the session ID generated after initiating the SSO session (codeA
), and required user details from your backend user management system (primary_key
,user_name
). Each of these parameters is defined in Add user information. - From your native app, make a call to the backend endpoint of the same backend system that made the
GET /sso/v1/register-user
call.
- From your backend system, make a
GET https://www.spot.im/api/sso/v1/register-user?code_a={CODE_A}&access_token={ACCESS_TOKEN}&primary_key={PRIMARY_KEY}&user_name={USER_NAME}
private func getCodeB(codeA: String) {
MyAuthenticationProvider.getCodeB(with: codeA,
// Some identification that this user is authenticated to your backend system
...) { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let codeB):
self.completeSSOWithSpotIm(codeB: codeB)
case .failure(let error):
handleError()
}
}
}
- Call
completeSSO
with thecodeB
.
private func completeSSOWithSpotIm(codeB: String) {
SpotIm.completeSSO(with: codeB) { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let userId):
// You can save the userId in case you support multiple users logged in at the same time in the application side
// Later on this userId can be checked with `SpotIm.getUserLoginStatus` function
break
case .failure(let error):
self.handleLoginError()
}
}
}
Third-party single sign-on
- Authenticate a user with your third-party user management vendor.
- Call the
ssoWithJwt(JWT)
function with a user JWT secret.
func authenticate(secret: String) {
SpotIm.sso(withJwtSecret: secret) { result in
switch result {
case .success(let ssoResponse):
guard ssoResponse.success else {
// Handle error
return
}
// Authenticated successfully
case .failure(let error):
// Handle error
break
}
}
}
Supporting signup/login flow
You can support instantiating a signup/login flow from the OpenWeb SDK UI by providing SpotImLoginDelegate
when instantiating the SpotImSDKFlowCoordinator
.
extension ArticleViewController: SpotImLoginDelegate {
func startLoginUIFlow(navigationController: UINavigationController) {
// Show your login UI flow here, you can either `push` or `present` it
// Once the flow is done and SSO is completed we will dismiss the whole navigation stack
// You can still dismiss your UI at the end, but we will do it regardless
}
func renewSSOAuthentication(userId: String) {
// Renew SSO - Basically silent SSO again to keep the user connected
// This function will be called once a token is no longer valid and a user was connected from before
// Follow the above steps to renew the SSO
}
}
When the startLoginUIFlow
delegate method is called, a UI should appear that allows the user to sign up or log in to the app. Upon successful login, the full SSO flow is performed using the OpenWeb SDK API. This process ensures that the user is logged in to the OpenWeb commenting system as well.
When the renewSSOAuthentication
delegate function is called, a silent SSO flow is performed. This re-authentication ensures the user remains logged in. This function is called in two primary situations:
- An authentication token has expired.
- An authentication error occurred, and a user was previously logged in.
The userId
field tracks which user was previously logged in. This tracking enables multiple logged-in users in the application using the SDK.
Display login prompt in full conversation
To add a customized login prompt above the full Conversation UI, you should implement the following optional SpotImLoginDelegate
function.
To customize the login prompt see the section of Custom UI.
Function | Description |
---|---|
func shouldDisplayLoginPromptForGuests() -> Bool | This should be overridden and return true . |
The following example shows how to override this function in SpotImLoginDelegate
.
extension ArticleViewController: SpotImLoginDelegate {
func shouldDisplayLoginPromptForGuests() -> Bool {
return true
}
}
Logout
Call the OpenWeb logout API whenever a user logs out of your system.
func logoutFromSpotIM() {
SpotIm.logout { result in
switch result {
case .success(_):
// "Logout from SpotIm was successful"
break
case .failure(let error):
// Handle error
break
}
}
}
Login status
The OpenWeb login status API enables you to understand the status of the current OpenWeb user.
The status of a current user will be either guest
or ssoLoggedIn(userId: String)
.
Login Status | Description |
---|---|
guest | Unregistered guest user |
ssoLoggedIn(userId: String) | Registered OpenWeb user |
getUserLoginStatus
Retrieve the login status of the current user.
func findUserLoginStatus() {
SpotIm.getUserLoginStatus { result in
switch result {
case .success(let loginStatus):
// You may login or do something after that
break
case .failure(let error):
// Handle error
break
}
}
}
Updated 11 months ago