Login
This guide is primarily for developers and potentially project managers who want to understand the Passport integration process.
Login with Next.js
This example demonstrates various login and logout implementations using the Immutable Passport SDK in a Next.js application. It showcases different authentication methods including login with EthersJS, identity-only login, and various logout strategies, along with authentication event handling.
Features Overview​
- Login with EthersJS integration
- Identity-only login (without wallet connection)
- Headless login options (Email, Google, Apple, Facebook)
- Bring Your Own Auth (Preview)
- Standard logout functionality
- Logout with redirect mode
- Silent logout implementation
- Authentication event handling
SDK Integration Details​
Login with EthersJS​
Integrates Passport authentication with EthersJS for wallet connection and interaction.
const passportProvider = await passportInstance.connectEvm();
const web3Provider = new BrowserProvider(passportProvider);
const accounts = await web3Provider.send('eth_requestAccounts', []);
This implementation uses EthersJS's BrowserProvider to interact with the Passport provider. It requests user accounts and manages the connection state, displaying the connected account address when successful.
Identity-only Login​
The login
method can be used to log in a user and retrieve their profile information without connecting to Immutable zkEVM.
const profile: passport.UserProfile | null = await passportInstance.login();
This will prompt the user to select an authentication option from within an iFrame, and open a popup to securely complete the authentication process.
Customising the login prompt​
For a more streamlined user experience, the standard Passport login prompt can be bypassed
by providing the directLoginOptions
parameter to the login
method. This allows you
to streamline the user experience by rendering a customised authentication prompt within your own application.
Once an authentication option (email, Google, Apple, or Facebook) is passed to the login
method, a popup will be opened so that the user can authenticate securely.
The directLoginOptions
object supports the following properties:
directLoginMethod
: The authentication provider (email
,google
,apple
, orfacebook
)email
: Required whendirectLoginMethod
isemail
, specifies the user's email addressmarketingConsentStatus
: Marketing consent setting (opted_in
orunsubscribed
)
// Headless login with email
const userProfile = await passport.login({
directLoginOptions: {
directLoginMethod: 'email',
email: 'user@example.com',
marketingConsentStatus: 'opted_in'
}
});
// Headless login with specific provider
const userProfile = await passport.login({
directLoginOptions: {
directLoginMethod: 'google', // or 'apple', 'facebook'
marketingConsentStatus: 'opted_in'
}
});
This approach offers a more streamlined user experience, particularly for games or applications that want to feature individual authentication options in their UI, and has been shown to lead to faster user onboarding and improved conversion rates.
Bring Your Own Auth (Preview)​
For users who already have an existing authentication system, migrating to Passport can be uneconomical, and introducing a double login process would result in poor user experience. With Bring Your Own Auth (BYOA), you can integrate Immutable Passport with your authentication system by exchanging tokens via the BYOA API.
The BYOA integration process involves:
1. Backend Authentication Request: Once the user is authenticated with your existing system, your backend server calls the BYOA API
Note: This step requires a secret API key which you can obtain from the Immutable Hub. For more details, see API Keys.
# Use https://api.sandbox.immutable.com for sandbox
curl --location 'https://api.immutable.com/v1/token-exchange' \\
--header 'x-immutable-api-key: YOUR_SECRET_API_KEY' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"email": "user@example.com",
"client_id": "YOUR_CLIENT_ID"
}'
2. Receive Passport Tokens: The BYOA API returns authentication tokens that your backend forwards to the application
{
"access_token": "ACCESS_TOKEN",
"id_token": "ID_TOKEN",
"refresh_token": "REFRESH_TOKEN",
"token_type": "Bearer",
"expires_in": 900
}
3. Complete Authentication: Call the Passport SDK to complete authentication by passing the tokens from your backend
// Complete authentication with BYOA tokens
const user = await passportInstance.storeTokens(tokenResponse);
Logout​
Provides a standard method to log the user out of the Passport session.
const logout = async () => {
if (!passportInstance || !isLoggedIn) return;
try {
await passportInstance.logout();
setIsLoggedIn(false);
setAccountAddress(null);
} catch (error) {
console.error('Error disconnecting:', error);
}
};
The standard logout implementation disconnects the user from Passport using the logout()
method. This ends the user's session and clears any authentication state.
Logout with Redirect Mode​
Configures Passport to redirect the user to a specified URL after logout.
export const passportInstance = new passport.Passport({
baseConfig: {
environment: config.Environment.SANDBOX,
publishableKey:
process.env.NEXT_PUBLIC_PUBLISHABLE_KEY || '<YOUR_PUBLISHABLE_KEY>',
},
clientId: process.env.NEXT_PUBLIC_CLIENT_ID || '<YOUR_CLIENT_ID>',
redirectUri: 'http://localhost:3000/redirect',
logoutMode: 'redirect',
logoutRedirectUri: 'http://localhost:3000/logout',
audience: 'platform_api',
scope: 'openid offline_access email transact',
});
This configuration sets up Passport to use 'redirect' mode for logout. When logout()
is called, the user will be redirected to the specified logoutRedirectUri
after being logged out.
Silent Logout​
Implements a logout process that happens in the background without redirecting the user's main window.
await passportInstance.logout();
This implementation shows how to implement a silent logout that disconnects the user without redirecting to another page, providing a seamless user experience.
Authentication Event Handling​
Demonstrates how to listen for and react to authentication events like account changes.
provider.on(ProviderEvent.ACCOUNTS_CHANGED, handleAccountsChanged);
const handleAccountsChanged = (accounts: string[]) => {
setAccountsState(accounts);
if (accounts.length === 0) {
setIsLoggedIn(false);
setAddress('');
setChainId('');
} else {
setAddress(accounts[0]);
}
};
This implementation shows how to listen for and handle authentication events, specifically the ACCOUNTS_CHANGED
event. It updates the application state when accounts are changed or disconnected, maintaining synchronization between the wallet state and the application.
Running the App​
Prerequisites​
- Node.js 16 or higher
- pnpm package manager
- Immutable Developer Hub account for environment setup
Local Setup Steps​
- Clone the repository:
git clone https://github.com/immutable/ts-immutable-sdk.git
- Navigate to the example directory:
cd examples/passport/login-with-nextjs
- Install dependencies:
pnpm install
Copy the
.env.example
file to.env
and update with your Passport client credentials from the Immutable Developer Hub.Start the development server:
pnpm dev
- Open your browser and navigate to
http://localhost:3000
Summary​
This example demonstrates various authentication patterns using the Immutable Passport SDK in a Next.js application. It showcases different login methods including EthersJS integration and identity-only authentication, various logout strategies (redirect and silent modes), and proper handling of authentication events. Developers can use this example as a reference for implementing comprehensive Passport authentication in their own Next.js applications.