React 中使用魔法链接进行身份验证

2025-06-05

React 中使用魔法链接进行身份验证

最近,通过魔法链接 (Magic Link) 进行用户身份验证的做法越来越流行(这并非偶然)。魔法链接会将一个唯一的链接发送到用户的邮箱,用户可以通过该链接注册/登录。它免去了用户名、密码、激活邮箱、忘记密码等麻烦。

magic.link提供了一个 npm 包,我们可以将其插入我们的应用程序并在几分钟内设置一个身份验证系统。

开始吧🚀

安装:

npm i magic-sdk
Enter fullscreen mode Exit fullscreen mode

导入并初始化魔法


import { Magic } from "magic-sdk";

const [user, setUser] = useState(null);

useEffect(() => {
    magic = new Magic(process.env.NEXT_PUBLIC_MAGIC_API_KEY)
}, []);
Enter fullscreen mode Exit fullscreen mode

NEXT_PUBLIC_MAGIC_API_KEY是 magic.link 提供的 api key,存储在本地环境中。

用户登录

const loginUser = async (email) => {
    try {
      await magic.auth.loginWithMagicLink({ email });
      setUser(email);
      router.push("/");
    } catch (err) {
      setUser(null);
      throw new Error("Email login failed");
    }
  };
Enter fullscreen mode Exit fullscreen mode

验证用户会话:

一旦用户点击邮件中收到的 magic 链接并完成身份验证,magic 就会自动将用户元数据存储在您网站的 localstorage/cookies 中。我们只需使用内置函数来获取存储的会话令牌和用户数据(此处为电子邮件)。

const checkUserLoggedIn = async () => {
  try {
    const isLoggedIn = await magic.user.isLoggedIn();
    if (isLoggedIn) {
      const { email } = await magic.user.getMetadata();
      setUser(email);
      getToken();
    }
  } catch (err) {
    throw new Error("User is not logged in");
  }
};

const getToken = async () => {
  try {
    return await magic.user.getIdToken();
  } catch (err) {
    throw new Error("Authenticate current session failed");
  }
};
Enter fullscreen mode Exit fullscreen mode

checkUserLoggedIn()在 useEffect 钩子中调用。

用户注销:

const logoutUser = async () => {
    try {
      await magic.user.logout();
      setUser(null);
      router.push("/");
    } catch (err) {
      throw new Error("User logout failed");
    }
  };
Enter fullscreen mode Exit fullscreen mode

Oauth登录:

你可以按照 Magic 账户下的社交登录快速设置指南进行操作。(相信我,这个指南并不长,只需要几分钟😄)完成后,我们就可以在应用中设置 OAuth 登录了。

安装:

npm i @magic-ext/oauth
Enter fullscreen mode Exit fullscreen mode

对我们的魔法初始化进行微小的改变以支持 oauth。

import { OAuthExtension } from "@magic-ext/oauth";

useEffect(() => {
    magic = new Magic(process.env.NEXT_PUBLIC_MAGIC_API_KEY, {
      extensions: [new OAuthExtension()],
    });
}, []);
Enter fullscreen mode Exit fullscreen mode
const oauthLogin = async (e) => {
    e.preventDefault();

    // Start the Google OAuth 2.0 flow!
    await magic.oauth.loginWithRedirect({
      provider: "google",
      redirectURI: `${window.location.origin}/oauth`,
    });
  };
Enter fullscreen mode Exit fullscreen mode

当用户点击“使用 Google 登录”按钮时,调用上述方法。这里,我提供了redirectURI。Google/oauth登录完成后,Magic 会重定向到我们网站的这个端点。我们可以在该端点下创建一个成功页面,或者直接重定向到主页,只需/使用/oauth

在我们的 useEffect 钩子中添加一些额外的逻辑:

useEffect(() => {
    magic = new Magic(process.env.NEXT_PUBLIC_MAGIC_API_KEY, {
      extensions: [new OAuthExtension()],
    });

    const render = async () => {
      if (window.location.pathname === "/oauth") {
        try {
          const result = await magic.oauth.getRedirectResult();
          const profile = JSON.stringify(result.oauth.userInfo, undefined, 2);
          if (profile.email) {
            setUser(profile.email);
            router.push("/");
          }
        } catch {
          window.location.href = window.location.origin;
          throw new Error("Oauth login failed");
        }
      }

      checkUserLoggedIn();
    };
    render();
  }, []);
Enter fullscreen mode Exit fullscreen mode

这里唯一的新东西是render()useEffect 内部的方法。它检查当前 URL 是否为/oauth,然后获取通过 OAuth 登录获得的用户详细信息。profile变量包含许多详细信息,但为了简单起见,这里我们仅使用电子邮件。


这样……🎉
我们为应用/网站设置了邮箱和谷歌登录。
再也不用担心密码带来的麻烦了。😌

来源:封面照片由FranckUnsplash上拍摄

📌 magic.link 目前提供 10000 个免费登录名,足以支持你的爱好/宠物项目。如果你感兴趣并想体验 magic,请点击此处注册😉

文章来源:https://dev.to/gogulaanand/authentication-with-magic-link-in-next-js-2k5p
PREV
2024 年必须摒弃的 5 个前端开发误区
NEXT
肯尼亚软件开发人员的生活