Using custom authentication in iOS SDK
Custom authentication is a way to authenticate users with your custom authentication service. For example, while authenticating with Google, you can use your own Google Client ID to authenticate users directly.
This feature, with MFA turned off, can even make Embedded Wallets invisible to the end user.
This is a paid feature and the minimum pricing plan to use this SDK in a production environment is the Growth Plan. You can use this feature in Web3Auth Sapphire Devnet network for free.
Get an Auth Connection ID
To enable this, you need to create a connection from the Authentication tab of your project from the Embedded Wallets developer dashboard with your desired configuration.
To configure a connection, you need to provide the particular details of the connection into our Embedded Wallets dashboard. This enables us to map an authConnectionId with your connection details. This authConnectionId helps us to identify the connection details while initializing the SDK. You can configure multiple connections for the same project, and you can also update the connection details anytime.
Learn more about the auth provider setup and the different configurations available for each connection.
Configuration
To use custom authentication (using supported social providers or login providers like Auth0, AWS Cognito, Firebase, or your own custom JWT login), you can add the configuration using the authConnectionConfig parameter during the initialization.
The authConnectionConfig parameter is an array of AuthConnectionConfig instances, each defining a specific authentication connection.
Parameters
After creating the auth connection from the Web3Auth Dashboard, you can use the following parameters in the AuthConnectionConfig.
- Table
- Struct
| Parameter | Description |
|---|---|
authConnectionId | The name of the auth connection that you have registered on the Web3Auth Dashboard. It's a mandatory field, and accepts String as a value. |
authConnection | Type of login of this auth connection. For example, if you choose .GOOGLE, a Google sign-in flow will be used. If you choose .CUSTOM, you should be providing your own JWT token, no sign-in flow will be presented. It's a mandatory field, and accepts AuthConnection as a value. |
clientId | Client ID provided by your login provider used for custom auth connection. For example, Google's Client ID or Web3Auth's Client ID if using .CUSTOM as AuthConnection. It's a mandatory field, and accepts String as a value. |
name? | Display name for the auth connection. If nil, the default name is used. It accepts String as a value. |
description? | Description for the button. If provided, it renders as a full length button, else icon button. It accepts String as a value. |
groupedAuthConnectionId? | The field in JWT token which maps to grouped auth connection ID. Please make sure you selected the correct JWT auth connection ID in the developer dashboard. It accepts String as a value. |
logoHover? | Logo to be shown on mouse hover. It accepts String as a value. |
logoLight? | Light logo for dark background. It accepts String as a value. |
logoDark? | Dark logo for light background. It accepts String as a value. |
mainOption? | Show login button on the main list. It accepts Bool as a value. Default is false. |
showOnModal? | Whether to show the login button on modal or not. Default is true. |
showOnDesktop? | Whether to show the login button on desktop. Default is true. |
showOnMobile? | Whether to show the login button on mobile. Default is true. |
public struct AuthConnectionConfig: Codable {
let authConnectionId: String
let authConnection: AuthConnection
let name: String?
let description: String?
let clientId: String
let groupedAuthConnectionId: String?
let logoHover: String?
let logoLight: String?
let logoDark: String?
let mainOption: Bool?
let showOnModal: Bool?
let showOnDesktop: Bool?
let showOnMobile: Bool?
let jwtParameters: ExtraLoginOptions?
let isDefault: Bool?
}
public enum AuthConnection: String, Codable {
case GOOGLE = "google"
case FACEBOOK = "facebook"
case REDDIT = "reddit"
case DISCORD = "discord"
case TWITCH = "twitch"
case APPLE = "apple"
case LINE = "line"
case GITHUB = "github"
case KAKAO = "kakao"
case LINKEDIN = "linkedin"
case TWITTER = "twitter"
case WEIBO = "weibo"
case WECHAT = "wechat"
case EMAIL_PASSWORDLESS = "email_passwordless"
case CUSTOM = "custom"
case SMS_PASSWORDLESS = "sms_passwordless"
case FARCASTER = "farcaster"
}
Usage
- JWT
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth",
authConnectionConfig: [
AuthConnectionConfig(
authConnectionId: "your-auth-connection-id", // Get it from Web3Auth Dashboard
authConnection: .GOOGLE,
clientId: "YOUR_GOOGLE_CLIENT_ID"
)
]
)
)
let result = try await web3Auth.connectTo(loginParams: LoginParams(authConnection: .GOOGLE))
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth",
authConnectionConfig: [
AuthConnectionConfig(
authConnectionId: "your-auth-connection-id", // Get it from Web3Auth Dashboard
authConnection: .FACEBOOK,
clientId: "YOUR_FACEBOOK_CLIENT_ID"
)
]
)
)
let result = try await web3Auth.connectTo(loginParams: LoginParams(authConnection: .FACEBOOK))
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth",
authConnectionConfig: [
AuthConnectionConfig(
authConnectionId: "your-auth-connection-id", // Get it from Web3Auth Dashboard
authConnection: .CUSTOM,
clientId: "YOUR_WEB3AUTH_CLIENT_ID"
)
]
)
)
let result = try await web3Auth.connectTo(loginParams: LoginParams(authConnection: .CUSTOM))
Configure extra login options
Additional to the auth connection config during initialization, you can pass extra options to the connectTo function to configure the login flow for cases requiring additional info. The ExtraLoginOptions accepts the following parameters.
Parameters
- Table
- Struct
| Parameter | Description |
|---|---|
additionalParams? | Additional params in [String: String] format for OAuth login, use id_token (JWT) to authenticate with Web3Auth. |
domain? | Your custom authentication domain as string. For example, if you are using Auth0, it can be example.au.auth0.com. |
client_id? | Client ID as string, provided by your login provider used for custom auth connection. |
leeway? | The value used to account for clock skew in JWT expirations. The value is in seconds, and ideally should be no more than 60 seconds or 120 seconds at max. It takes integer value. |
userIdField? | The field in JWT token which maps to user ID. Please make sure you selected the correct JWT user ID in the developer dashboard. It accepts a string value. |
isUserIdCaseSensitive? | Boolean to confirm whether the user ID field is case sensitive or not. |
display? | Allows developers to configure the display of UI. It accepts a string value. |
prompt? | Prompt shown to the user during authentication process. It accepts a string value. |
max_age? | Max time allowed without reauthentication. If the last time user authenticated is greater than this value, then user must reauthenticate. It accepts a string value. |
ui_locales? | The space separated list of language tags, ordered by preference. For instance fr-CA fr en. |
id_token_hint? | It denotes the previously issued ID token. It accepts a string value. |
id_token? | JWT (ID token) to be passed for login. |
access_token? | Access token for OAuth flows. It accepts a string value. |
flow_type? | Specifies the email passwordless flow type. Accepts EmailFlowType (.code or .link). |
acr_values? | acr_values |
scope? | The default scope to be used on authentication requests. It accepts a string value. |
audience? | The audience, presented as the aud claim in the access token. It accepts a string value. |
connection? | The name of the connection configured for your application. If nil, it will redirect to the Auth0 login page. It accepts a string value. |
state? | state |
response_type? | Defines which grant to execute for the authorization server. It accepts a string value. |
nonce? | nonce |
redirect_uri? | It can be used to specify the default URL where your custom JWT verifier can redirect your browser to with the result. If you are using Auth0, it must be allowlisted in the Allowed Callback URLs in your Auth0's application. |
public struct ExtraLoginOptions: Codable {
let display: String?
let prompt: String?
let max_age: String?
let ui_locales: String?
let id_token_hint: String?
let id_token: String?
var login_hint: String?
let acr_values: String?
let scope: String?
let audience: String?
let connection: String?
let domain: String?
let client_id: String?
let redirect_uri: String?
let leeway: Int?
let userIdField: String?
let isUserIdCaseSensitive: Bool?
let additionalParams: [String: String]?
let access_token: String?
let flow_type: EmailFlowType?
}
public enum EmailFlowType: String, Codable {
case code = "code"
case link = "link"
}
Single auth connection example
- Auth0
- Custom JWT
- Email Passwordless
- SMS Passwordless
Auth0 has a special login flow called the SPA flow. This flow requires a client_id and domain to be passed, and Web3Auth will get the JWT id_token from Auth0 directly. You can pass these configurations in the ExtraLoginOptions object in the login function.
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth",
authConnectionConfig: [
AuthConnectionConfig(
authConnectionId: "your-auth-connection-id", // Get it from Web3Auth Dashboard
authConnection: .CUSTOM,
clientId: "YOUR_AUTH0_CLIENT_ID"
)
]
)
)
let result = try await web3Auth.connectTo(
loginParams: LoginParams(
authConnection: .CUSTOM,
extraLoginOptions: ExtraLoginOptions(
domain: "https://username.us.auth0.com", // Domain of your Auth0 app
userIdField: "sub" // The field in JWT token which maps to user ID
)
)
)
If you're using any other provider like Firebase, AWS Cognito, or deploying your own custom JWT server, you need to put the JWT token into the idToken field of LoginParams. For SFA (Single Factor Auth) mode, this enables direct authentication without additional login flows.
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth",
authConnectionConfig: [
AuthConnectionConfig(
authConnectionId: "your-auth-connection-id", // Get it from Web3Auth Dashboard
authConnection: .CUSTOM,
clientId: "YOUR_WEB3AUTH_CLIENT_ID"
)
]
)
)
let result = try await web3Auth.connectTo(
loginParams: LoginParams(
authConnection: .CUSTOM,
authConnectionId: "your-auth-connection-id",
idToken: "your_jwt_token" // Direct SFA authentication
)
)
To use the Email Passwordless login, you need to put the email into the loginHint parameter of the LoginParams. By default, the login flow will be code flow. If you want to use the link flow, you need to put flow_type into the extraLoginOptions.
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth"
)
)
let result = try await web3Auth.connectTo(
loginParams: LoginParams(
authConnection: .EMAIL_PASSWORDLESS,
loginHint: "hello@web3auth.io",
extraLoginOptions: ExtraLoginOptions(
flow_type: .code // Use .code for OTP flow or .link for magic link flow
)
)
)
To use the SMS Passwordless login, send the phone number as the loginHint parameter of LoginParams. Please ensure the phone number takes the format: +{country_code}-{phone_number}, for example +91-9911223344.
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth"
)
)
let result = try await web3Auth.connectTo(
loginParams: LoginParams(
authConnection: .SMS_PASSWORDLESS,
loginHint: "+91-9911223344"
)
)
Grouped auth connection example
You can use grouped auth connections to combine multiple login methods to get the same address for the users regardless of their login providers. For example, combining a Google and Email Passwordless login, or Google and GitHub via Auth0 to access the same address for your user.
import Web3Auth
let web3Auth = try await Web3Auth(
options: Web3AuthOptions(
clientId: "YOUR_WEB3AUTH_CLIENT_ID",
web3AuthNetwork: .SAPPHIRE_MAINNET,
redirectUrl: "com.yourapp.bundleid://auth",
authConnectionConfig: [
AuthConnectionConfig(
authConnectionId: "aggregate-sapphire",
groupedAuthConnectionId: "w3a-google",
authConnection: .GOOGLE,
name: "Aggregate Login",
clientId: "YOUR_GOOGLE_CLIENT_ID"
),
AuthConnectionConfig(
authConnectionId: "aggregate-sapphire",
groupedAuthConnectionId: "w3a-a0-email-passwordless",
authConnection: .CUSTOM,
name: "Aggregate Login",
clientId: "YOUR_AUTH0_CLIENT_ID"
)
]
)
)
func loginWithGoogle() async throws {
let result = try await web3Auth.connectTo(loginParams: LoginParams(authConnection: .GOOGLE))
}
func loginWithGitHub() async throws {
let result = try await web3Auth.connectTo(
loginParams: LoginParams(
authConnection: .CUSTOM,
extraLoginOptions: ExtraLoginOptions(
connection: "github",
domain: "https://web3auth.au.auth0.com",
userIdField: "email",
isUserIdCaseSensitive: false
)
)
)
}