将 LinkedIn OpenID 登录添加到您的应用的三步指南(2025 版)🚀

我正在致力于将 **LinkedIn Sign-In** 集成到我的产品 LiveAPI 中,但是,让我告诉你,这一切并非一帆风顺。

今天我花了三个小时来解决大多数人在过程中遇到的 3-4 个棘手问题。

因此,为了让您避免同样的陷阱,我写了这篇文章来指导您逐步完成集成。

如果您在跟随过程中遇到任何障碍,请随时**发表评论**,我很乐意为您提供帮助。

如果您计划稍后整合 LinkedIn,请**立即收藏本文**——未来您会感谢您!

只需**三步**,您的应用即可连接到 LinkedIn 的 OpenID 魔法。让我们开始吧,好吗?

Image description

步骤 1:创建 LinkedIn 应用程序

在开始编码之前,我们需要在 LinkedIn 的开发者门户中创建一个应用程序。

1. 创建你的 LinkedIn 应用

前往 LinkedIn 开发者应用程序,输入您的应用程序名称、隐私政策并上传您的徽标。

提示:使用明确的隐私政策,如本例:隐私政策。

Image description

2. 生成客户端 ID 和密钥

  • 创建应用程序后,生成客户端机密。
  • 将前端和后端的客户端 ID 保存为环境变量,但请记住 - 将 Secret 安全地保存在后端。
  • Image description

    3. 设置重定向 URL

    在 **重定向 URL** 部分添加以下 URL:

  • 本地服务器:http://localhost:3000/signin
  • 生产服务器:https://yourdomain.com/signin
  • Image description

    4. 启用魔法

  • 转到 Auth 选项卡并请求访问权限:使用 OpenID Connect 登录 LinkedIn 在 LinkedIn 上分享
  • 检查您的端点以查看 GET /v2/userinfo 是否已激活。
  • Image description

    5. 验证您的应用

    转到应用的**设置选项卡**并验证按钮功能。如果没有这个,您的用户可能会无所适从!

    Image description

    6. 获取 LinkedIn 按钮图片

    从这里下载官方 LinkedIn 登录按钮资产。

    第 2 步:构建前端

    让我们开始编写代码吧!您需要一个专用组件来处理 LinkedIn 登录。

    1. 创建 linkedin.jsx

    import { Component } from "react";
    
    class LinkedIn extends Component {
      componentDidMount() {
        this.handleRedirect();
      }
    
      handleRedirect = () => {
        const urlParams = new URLSearchParams(window.location.search);
        const redirectUri = localStorage.getItem("linkedInRedirectUri");
        const savedState = localStorage.getItem("linkedInState");
    
        localStorage.removeItem("linkedInState");
        localStorage.removeItem("linkedInRedirectUri");
    
        const state = urlParams.get("state");
        const code = urlParams.get("code");
        const error = urlParams.get("error");
    
        // Clear URL parameters after handling
        let newURL = window.location.pathname;
        urlParams.delete("state");
        urlParams.delete("error");
        urlParams.delete("error_description");
        urlParams.delete("code");
        if (urlParams.toString()) {
          newURL = `${newURL}?${urlParams.toString()}`;
        }
        window.history.replaceState(null, null, newURL);
    
        if (error) {
          this.props.callback(error, null, null);
        } else if (redirectUri && code && savedState === state) {
          this.props.callback(null, code, redirectUri);
        }
      };
    
      startLogin = () => {
        const { clientId, scope } = this.props;
        const state = Math.random().toString(36).substring(7);
        localStorage.setItem("linkedInState", state);
        localStorage.setItem("linkedInRedirectUri", window.location.href);
    
        const loginUrl = getURL(clientId, state, scope);
        window.location.href = loginUrl; // Redirect to LinkedIn OAuth
      };
    
      render() {
        return (
          
        );
      }
    }
    
    export default LinkedIn;
    
    const getURL = (clientId, state, scope) => {
      const redirectUri = encodeURIComponent(window.location.href);
      const base =
        "https://www.linkedin.com/oauth/v2/authorization?response_type=code&";
      const fullScope = scope?.length
        ? `&scope=${encodeURIComponent(scope.join(" "))}`
        : "";
    
      return `${base}client_id=${clientId}&redirect_uri=${redirectUri}&state=${state}${fullScope}`;
    };

    2. 为 LinkedIn 按钮添加 CSS

    .linkedin-button {
      border: none;
      background: transparent;
      padding: 0;
      cursor: pointer;
    }
    
    .linkedin-icon {
      height: auto;
    }
    
    .linkedin-button:hover .linkedin-icon {
      content: url("/src/assets/images/Sign-In-Small---Hover.png");
    }

    👉 使用您之前从官方 LinkedIn zip 文件夹下载的按钮图像。

    3. 集成登录按钮

    import "./assets/styles/main.scss";
    import { useState } from "react";
    import LinkedIn from "./linkedin"; 
    
    const Linkedin_ClientID = "867mq7ml7hx0gm"; 
    
    function LinkedinPage() {
      const [authData, setAuthData] = useState(null);
    
      const handleLinkedInCallback = async (error, code, redirectUri) => {
        if (error) {
          console.error("LinkedIn login error:", error);
          return;
        }
        setAuthData(code);
        console.log("LinkedIn code:", code);
        console.log("Redirect URI:", redirectUri);
    
        // Prepare token exchange request
        // Send the code to the backend from here
      };
    
      return ( 
          

    Credential: {authData}

    ); } export default LinkedinPage;

    ⚠️ **重要说明**:

  • 将您的 scope={["openid", "profile", "email"]} 设置为仅您的应用被授予访问权限的范围。
  • 不要相信你在互联网上找到的随机范围——它不起作用。
  • 步骤 3:编写后端代码

    好吧,现在是时候戴上你的调试斗篷并深入后端了!

    但在开始之前,让我先用这些智慧金句来告诉你,这样你就不会睡不着觉了:

    重要说明(又称调试备忘单)

  • 代码的有效期只有 20 秒 是的,你没看错。你从前端 UI 获得的授权代码的有效期只有 20 秒。超过 20 秒,它就失效了。所以如果遇到错误,不要惊慌——这可能是一个时间问题。
  • 重定向 URI 一致性是关键 您在前端使用的重定向 URI 必须与后端 API 调用中的重定向 URI 匹配。任何不匹配都会导致错误,让您质疑自己的人生选择 xD。
  • 现在,让我们开始编码吧!

    1. 声明常量

    首先定义 LinkedIn API 所需的所有变量:

    const LINKEDIN_CLIENT_ID = "867mq7ml7hm";
    const LINKEDIN_CLIENT_SECRET = "WPL_FAKE_=";
    const LINKEDIN_ACCESS_TOKEN_URL = "https://www.linkedin.com/oauth/v2/accessToken";
    const LINKEDIN_USERINFO = "https://api.linkedin.com/v2/userinfo";
    const LINKEDIN_REDIRECTION_URI = "http://localhost:5173/";

    2. 使用 LinkedIn 代码兑换访问令牌

    后端的第一步是将短期授权码交换为访问令牌。以下是该 API:

    async function exchangeLinkedInCodeForToken(code) {
      const myHeaders = new Headers();
      myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
    
      const urlencoded = new URLSearchParams();
      urlencoded.append("grant_type", "authorization_code");
      urlencoded.append("code", code);
      urlencoded.append("redirect_uri", LINKEDIN_REDIRECTION_URI);
      urlencoded.append("client_id", LINKEDIN_CLIENT_ID);
      urlencoded.append("client_secret", LINKEDIN_CLIENT_SECRET);
    
      const requestOptions = {
        method: "POST",
        headers: myHeaders,
        body: urlencoded,
        redirect: "follow",
      };
    
      try {
        const response = await fetch(LINKEDIN_ACCESS_TOKEN_URL, requestOptions);
        const result = await response.text();
        console.log(result);
        const res = JSON.parse(result);
        return res.access_token;
      } catch (error) {
        console.error(error);
        throw error;
      }
    }

    提示:如果访问令牌交换失败,请仔细检查**已验证的应用程序?**、**请求的范围**、**代码**、**重定向 URI**,以及您是否在 20 秒的时间范围内。

    3. 检索 LinkedIn 会员详细信息

    获得访问令牌后,您可以调用 LinkedIn 的 **userinfo** API 来获取用户的个人资料信息:

    async function retrieveMemberDetails(accessToken) {
      const myHeaders = new Headers();
      myHeaders.append("Authorization", `Bearer ${accessToken}`);
    
      const requestOptions = {
        method: "GET",
        headers: myHeaders,
        redirect: "follow",
      };
    
      try {
        const response = await fetch(LINKEDIN_USERINFO, requestOptions);
        const result = await response.json();
        console.log(result);
        return {
          name: result.name,
          profile: result.picture,
          email: result.email,
        };
      } catch (error) {
        console.error(error);
        throw error;
      }
    }

    4. 实际测试 UserInfo API

    现在,把这些点连接起来:

  • 从前端获取授权码。
  • 使用 exchangeLinkedInCodeForToken 将其交换为访问令牌。
  • 使用retrieveMemberDetails获取用户的个人资料详细信息。
  • Image description

    瞧,LinkedIn 身份验证已完成!🎉

    Image description

    给你一份小礼物

    请允许我花一点时间来介绍一个可以帮我摆脱 API 文档混乱的工具——**LiveAPI**。

    LiveAPI 利用您的存储库并输出令人惊叹的安全 API 文档。

    **奖励:**您可以直接从文档执行 API 并以任何语言生成请求片段。

    实际操作如下:

    Image description

    如果您厌倦了分散的 API 说明或不稳定的 Postman 集合,不妨尝试一下。

    祝您编码愉快,愿 OAuth 之神对您的 LinkedIn 集成报以微笑!

    请继续关注下一部分,我们将更深入地探究 LinkedIn API 的魔力。