Magic Links
Magic Links
#Overview
Authenticate a user passwordlessly using a "magic link" sent to the specified user's email address.
#Compatibility
Only available with Dedicated Wallet.
Magic link SDK methods are available via the Web client-side SDK. These methods are deprecated on all mobile SDKs.
#Usage
The loginWithMagicLink
function sends an authentication request to the user. The resolved value is a Decentralized ID token with a default 15-minute lifespan. Refer to the API documentation for information on how to install and initialize Magic.
01import { Magic } from 'magic-sdk';
02
03// must use a Dedicated Wallet API Key
04const magic = new Magic('API_KEY');
05
06// log in a user by their email
07try {
08 await magic.auth.loginWithMagicLink({ email: 'hello@example.com' });
09} catch {
10 // Handle errors if required!
11}
12
13// log in a user by their email, without showing an out-of-the box UI.
14try {
15 await magic.auth.loginWithMagicLink({ email: 'hello@example.com', showUI: false });
16} catch {
17 // Handle errors if required!
18}
#Error Handling
To achieve a fully white-labeled experience, you will need to implement some custom error handling according to your UI needs. Here's a short example to illustrate how errors can be caught and identified by their code:
01import { Magic, RPCError, RPCErrorCode } from 'magic-sdk';
02
03const magic = new Magic('API_KEY');
04
05try {
06 await magic.auth.loginWithMagicLink({ email: 'hello@example.com', showUI: false });
07} catch (err) {
08 if (err instanceof RPCError) {
09 switch (err.code) {
10 case RPCErrorCode.MagicLinkFailedVerification:
11 case RPCErrorCode.MagicLinkExpired:
12 case RPCErrorCode.MagicLinkRateLimited:
13 case RPCErrorCode.UserAlreadyLoggedIn:
14 // Handle errors accordingly :)
15 break;
16 }
17 }
18}
#Test Mode
Magic's client-side Web SDK provides Test Mode as a quick way to test your integration locally by asserting specific error codes or bypassing the magic link flow completely. Test Mode only works when logging in with Magic links. As the name suggests, this is for testing. Users and wallets created in test mode should not be treated as secure or production-ready. Data surfaced while in Test Mode should not be considered secure, accurate, or production-ready.
To enable Test Mode, provide testMode: true
to the SDK constructor.
01import { Magic } from 'magic-sdk';
02
03const magic = new Magic('YOUR_API_KEY', {
04 testMode: true,
05});
With Test Mode enabled, you can assert the desired behavior through the email address you provide to loginWithMagicLink
:
- To assert a success state, use
test+success@magic.link
- To assert a failed state, use
test+fail@magic.link
- To assert a case-specific failed state, provide an RPC error code with
test+fail_with_{RPC_ERROR_CODE}@magic.link
01magic.auth.loginWithMagicLink({ email: 'test+success@magic.link' });
Web3 and blockchain use-cases sometimes require access to deterministic key-pairs so that testnet funds are available at runtime. To enable this, users can explicitly specify the key-pair associated to a test user with the following email: test+success_with_{PUBLIC_KEY:PRIVATE_KEY}@magic.link
.
The key-pair provided in the email address during test mode is not protected by Magic's delegated key management system. These keys should not be considered secure or private. Never store mainnet funds with these keys!
In practice, you can assert a successful login with:
01magic.auth.loginWithMagicLink({
02 email:
03 'test+success_with_{0x89A3983da27fF0eFCF901F74C4df84e0450A17B7:0x19de850af732e9e5745915162d707d6d8cf013ce7b2862e93081b0c8883bdfae}@magic.link',
04});
In the example above, we encode an Ethereum-compatible key-pair in the test user's email address. The login method will immediately resolve with a success state, bypassing the passwordless flow and enabling Ethereum or EVM-compatible signing methods to work seamlessly with your existing Web3 code.
#Security Notes
#IP Address Verification
Magic’s top priority is ensuring secure authentication for your end users in your app. Magic recently implemented and added a layer of security for all login flows with email magic link. Specifically, the change ensures that the IP address associated with the device that a user enters their email address on matches the IP address associated with the device that clicks the magic link. If the IP address does not match, the following error is shown to the user when they click on the magic link.
In addition, for desktop web users, magic links will now authenticate the session clicked from a user’s email. This means that the session or browser tab where the user first enters their email address will no longer sign the user in. This will help ensure that users remain secure in an evolving threat environment, while still delivering a smooth sign-in experience. For customers using the web SDK, there are no code changes required.
#Mobile Support
Magic Links are no longer supported on mobile as of June 20th, 2023. We advise customers to switch over to Email OTP instead. Please refer to the documentation below on how to implement OTP on mobile.
How to add OTP email login on iOS
How to add OTP email login on Android
How to add OTP email login on Flutter
How to add OTP email login on Unity
How to add OTP email login in React Native