You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Passport.js LinkedIn策略获取用户资料失败问题排查

Node.js中Passport-LinkedIn-OAuth2获取用户资料失败:InternalOAuthError

问题描述

我在Node.js应用中使用Passport.js和passport-linkedin-oauth2包实现LinkedIn认证,登录重定向后遇到以下错误:

InternalOAuthError: failed to fetch user profile
at Strategy. (C:\Users\jahed\MdShayemurRahman-github\002-thesis\backend\node_modules\passport-linkedin-oauth2\lib\oauth2.js:57:19)
at passBackControl (C:\Users\jahed\MdShayemurRahman-github\002-thesis\backend\node_modules\oauth\lib\oauth2.js:132:9)
at IncomingMessage. (C:\Users\jahed\MdShayemurRahman-github\002-thesis\backend\node_modules\oauth\lib\oauth2.js:157:7)
at IncomingMessage.emit (node:events:526:35)
at endReadableNT (node:internal/streams/readable:1408:12)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21)

已核对clientID、clientSecret、callbackURL与LinkedIn开发者平台配置完全一致,账号也授予了必要权限,试过重启服务器和更换网络,问题依然存在。

相关代码片段:

import express from 'express';
import cors from 'cors';
import passport from 'passport';
import session from 'express-session';

import { Strategy as LinkedInStrategy } from 'passport-linkedin-oauth2';


const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
  session({
    secret: process.env.SESSION_SECRET, 
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: false, 
    },
  })
);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, done) => {
  done(null, user);
});

passport.deserializeUser((user, done) => {
  done(null, user);
});

passport.use(
  new LinkedInStrategy(
    {
      clientID: process.env.LINKEDIN_CLIENT_ID,
      clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
      callbackURL: process.env.LINKEDIN_CALLBACK_URL,
      scope: ['openid', 'profile', 'w_member_social', 'email'],
    },
    (accessToken, refreshToken, profile, done) => {
      return done(null, profile);
    }
  )
);

app.get('/', (req, res) => {
  res.send(
    `<center style="font-size:140%"> <p>LOGIN </p>
      <img style="cursor:pointer;" onclick="window.location='/auth/linkedin'" src="http://bkpandey.com/wp-content/uploads/2017/09/linkedinlogin.png"/>
      </center>
      `
  );
});

app.get('/auth/linkedin', passport.authenticate('linkedin'));

app.get(
  '/auth/linkedin/callback',
  passport.authenticate('linkedin', {
    successRedirect: '/profile',
    failureRedirect: '/',
  })
);

// Route to handle successful authentication
app.get('/profile', (req, res) => {
  res.send('You are authenticated with LinkedIn!');
});


export default app;

错误原因及解决方法

1. API版本兼容性问题

passport-linkedin-oauth2旧版本默认使用已被LinkedIn弃用的v1用户资料API,无法适配当前v2接口,导致获取资料失败。

解决:

  • 升级passport-linkedin-oauth2至v2.0.0及以上版本,新版本已支持LinkedIn v2 API。
  • 若无法升级,可手动指定v2资料接口,在Strategy配置中添加:
    new LinkedInStrategy({
      // 原有配置...
      profileURL: 'https://api.linkedin.com/v2/userinfo',
      scope: ['openid', 'r_liteprofile', 'r_emailaddress'] // 替换原scope为v2对应权限
    }, ...)
    

2. 权限配置不匹配

LinkedIn v2 API对权限划分更细,需确保应用权限与代码声明的scope一致:

  • 登录LinkedIn开发者平台,进入应用「产品」页面,确认已添加「Sign In with LinkedIn」产品。
  • 在「权限」设置中启用r_liteprofile(基础资料)和r_emailaddress(邮箱)权限。
  • 代码中scope改为['openid', 'r_liteprofile', 'r_emailaddress'],移除不需要的w_member_social(该权限用于内容分享,与获取用户资料无关)。

3. 环境变量未正确加载

确认process.env中的认证参数已被正确读取,可添加日志验证:

console.log('Client ID:', process.env.LINKEDIN_CLIENT_ID);
console.log('Callback URL:', process.env.LINKEDIN_CALLBACK_URL);

若输出为undefined,检查.env文件配置或环境变量注入方式是否正确。

4. 回调URL的HTTPS要求

LinkedIn要求生产环境回调URL必须为HTTPS;本地开发使用localhost可忽略,但使用自定义域名时必须配置HTTPS:

  • 本地开发临时方案:使用http://localhost:端口/auth/linkedin/callback作为回调URL。
  • 或用ngrok等工具将本地服务映射为HTTPS地址,同步更新LinkedIn平台的回调URL配置。

5. Session配置问题

确保session配置生效:

  • 本地开发使用HTTP时,cookie.secure必须设为false(代码已配置,可确认是否被其他逻辑覆盖)。
  • session.secret需设置为非空字符串,避免session状态丢失影响OAuth流程。

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:06:19