Overview & Concepts

Authentication in social.plus

social.plus uses a dual authentication approach to ensure both application security and user verification:

API Key

Purpose: Identifies your application to social.plus servers
Scope: Application-level authentication
Usage: Required for SDK initialization
Security: Keep secure, never expose in client code

Auth Token

Purpose: Server-to-server verification that the user is validated by your backend
Scope: User-level authentication with your system
Usage: Optional for development, required for production
Security: Generated by your backend, proves user is legitimate

How Auth Tokens Work

Auth tokens enable server-to-server communication between social.plus and your backend:
1

User Authentication

Your app authenticates the user with your own authentication system (login, OAuth, etc.)
2

Backend Token Generation

Your backend server generates an auth token for the verified user and sends it to your app. Learn how to implement this →
3

social.plus Verification

When your app logs into social.plus, the auth token proves to social.plus that your backend has verified this user
4

Secure Communication

social.plus can now trust that this user session is legitimate and validated by your system
Why Auth Tokens? This approach ensures that only users who have been properly authenticated by your backend can access social.plus features, maintaining security and preventing unauthorized access.

When Do You Need Each?

// Production mode - API key + auth tokens
const client = Client.create({
  apiKey: 'your-prod-api-key',
  region: 'sg'
});

// Secure login with auth token from your backend
await client.login({
  userId: 'user-123',
  displayName: 'John Doe',
  authToken: 'token-generated-by-your-backend' // Proves user is verified by your system
});
Auth tokens must be generated by your secure backend after verifying the user. This ensures server-to-server trust between social.plus and your authentication system.

Quick Start (Basic Authentication)

Step 1: Initialize the SDK

Start by setting up the social.plus client with your API key:
let client = try! AmityClient(apiKey: "your-api-key", region: .SG)

Step 2: Login User

Authenticate users to access social.plus features:
Task { @MainActor in
    do {
        try await client.login(
            userId: "user-123",
            displayName: "John Doe",
            authToken: "your-auth-token", // Optional for development
            sessionHandler: sessionHandler
        )
        print("Login successful")
    } catch {
        print("Login failed: \(error)")
    }
}

Step 3: Check Authentication Status

Verify if a user is currently logged in:
if (client.sessionState == .established) {
    let currentUserId = client.getCurrentUserId()
    print("Current user: \(currentUserId)")
} else {
    // Proceed to social.plus Authentication
    authenticateToSocialPlus()
}

Step 4: Logout

End the user session: For an extra layer of security, which ensures accessToken revocation prior to performing logout(). Should the SDK fail to revoke the accessToken, the SDK will not proceed to logout and will throw an exception to notify the failure.
do {
    try await client.secureLogout()
} catch {
    /// Handle error from revoking accessToken here
}

Understanding Session States

Session states indicate what’s happening with user authentication. social.plus SDK automatically manages these states according to the flow shown in the diagram below:

notLoggedIn

Ready for login - user needs to authenticate
Entry points: App start (no session), logout, login failure

establishing

Login in progress - authentication being processed
Entry point: When login() is called from notLoggedIn state

established

Fully authenticated - SDK ready, all features available
Entry points: Successful login, successful token renewal

tokenExpired

Token renewal needed - automatic renewal attempted
Entry point: When auth token expires during established state

terminated

Session forcibly ended - user banned or deleted
Entry points: User banned/deleted from established or tokenExpired states

Session Flow

Understanding the complete session state flow helps you build responsive apps:
1

SDK Initialization

App starts: Always begins in the start state, then immediately moves to:
  • No saved session: Moves to notLoggedIn state
  • Has saved session: Moves to established state (if session valid)
2

Login Process

User attempts login:
  • notLoggedInestablishing (login in progress)
  • Login succeeds: establishingestablished
  • Login fails: establishingnotLoggedIn
3

Active Session Management

During active use in established state:
  • Token expires: establishedtokenExpired
  • Token renewed successfully: tokenExpiredestablished
  • User banned/deleted: establishedterminated
  • Manual logout: establishednotLoggedIn
4

Token Expiration Handling

When in tokenExpired state:
  • Auto-renewal succeeds: Returns to established state
  • Auto-renewal fails: User may need to re-authenticate
  • User banned during renewal: Moves to terminated state
  • Manual logout: Moves to notLoggedIn state
5

Session Termination

From terminated state:
  • Only way out is through logout → notLoggedIn
  • User must re-authenticate to access features again
Session State Flow Diagram

Observing Session State

Monitor session state changes to handle authentication in your app:
var cancellable: AnyCancellable?
// Observe session state changes
cancellable = client.$sessionState.sink { sessionState in
    switch sessionState {
    case .notLoggedIn:
        // Show login screen
        self?.showLogin()
    case .establishing:
        // Show loading indicator
        self?.showLoading()
    case .established:
        // Hide loading indicator, proceed to app
        self?.hideLoading()
        self?.proceedToApp()
    case .tokenExpired:
        // Attempt to refresh token (Optional)
        self?.showTokenRefreshIndicator()
    case .terminated:
        // Handle session termination
        self?.handleTermination()
    }
}

Advanced Session Management

For production apps, you’ll need sophisticated session handling with automatic token refresh:

Session Handlers for Token Refresh

Session handlers automatically manage token lifecycle:
class ProductionSessionHandler: AmitySessionHandler {
    func sessionWillRenewAccessToken(renewal: AccessTokenRenewal) {
        // Call your backend to get a fresh token
        AuthService.shared.refreshToken { result in
            switch result {
            case .success(let newToken):
                renewal.renewWithAuthToken(withAuthToken: newToken)
            case .failure(let error):
                print("Token refresh failed: \(error)")
                renewal.unableToRetrieveAuthToken()
            }
        }
    }
}

// Use during login
let sessionHandler = ProductionSessionHandler()
try await client.login(
    userId: userId,
    displayName: displayName,
    authToken: authToken,
    sessionHandler: sessionHandler
)

Security Best Practices

Production Token Management

Authentication Best Practices

Troubleshooting

Next Steps