如何通过LinkedIn JS SDK获取可用于后端REST调用的AccessToken?
解决LinkedIn JS SDK登录后后端REST调用401的官方方案
我之前踩过一模一样的坑!LinkedIn的JS SDK生成的客户端AccessToken确实没法直接给后端调用REST API——这俩令牌属于不同的权限体系,官方明确限制了前者只能在前端使用。下面给你一套完全符合官方规范的解决方案,用**授权码流程(Authorization Code Flow with PKCE)**来实现安全的后端数据获取:
核心思路
JS SDK负责触发用户授权并拿到授权码(Authorization Code),前端把这个授权码传给后端,由后端用授权码兑换成后端可用的OAuth2 AccessToken,最后用这个合法的令牌调用LinkedIn的REST接口获取用户数据。全程符合LinkedIn的安全要求,且有官方文档支持。
具体步骤
1. 前端用JS SDK发起授权(带PKCE)
首先初始化LinkedIn JS SDK时,要指定response_type: 'code',同时生成PKCE的code_challenge和code_verifier(PKCE是官方要求的安全机制,防止授权码被劫持)。
// 生成PKCE的verifier和challenge(可以用现成的库比如crypto-js,或者自己实现) function generatePKCE() { const verifier = Array.from(crypto.getRandomValues(new Uint8Array(32))) .map(b => b.toString(16).padStart(2, '0')) .join(''); const encoder = new TextEncoder(); const data = encoder.encode(verifier); return crypto.subtle.digest('SHA-256', data) .then(digest => btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')) .then(challenge => ({ verifier, challenge })); } // 初始化并发起授权 generatePKCE().then(({ verifier, challenge }) => { // 把verifier存在前端(比如sessionStorage),后面要传给后端 sessionStorage.setItem('linkedin_pkce_verifier', verifier); window.IN.init({ clientId: 'YOUR_CLIENT_ID', redirectUri: 'YOUR_REDIRECT_URI', // 和后台配置的一致 responseType: 'code', scope: 'r_liteprofile r_emailaddress', // 按需申请权限 codeChallenge: challenge, codeChallengeMethod: 'S256' }); // 触发登录授权 window.IN.User.authorize(() => { // 授权成功后,获取授权码 const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get('code'); // 把code传给后端 fetch('/your-backend-endpoint', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: code, pkce_verifier: sessionStorage.getItem('linkedin_pkce_verifier') }) }); }); });
2. 后端兑换授权码为后端可用的AccessToken
后端收到前端传来的code和pkce_verifier后,调用LinkedIn的令牌端点兑换令牌:
# 示例用Python,其他语言逻辑一致 import requests def exchange_code_for_token(code, pkce_verifier): token_url = 'https://www.linkedin.com/oauth/v2/accessToken' payload = { 'grant_type': 'authorization_code', 'code': code, 'redirect_uri': 'YOUR_REDIRECT_URI', # 和前端、后台配置一致 'client_id': 'YOUR_CLIENT_ID', 'client_secret': 'YOUR_CLIENT_SECRET', # 绝对不能暴露给前端 'code_verifier': pkce_verifier } response = requests.post(token_url, data=payload) token_data = response.json() return token_data['access_token'] # 这个就是后端能用的令牌
3. 后端用合法令牌调用REST API获取用户数据
拿到后端AccessToken后,就可以安全调用LinkedIn的REST接口了:
def get_linkedin_user_data(access_token): # 获取基本用户信息 profile_url = 'https://api.linkedin.com/v2/me' headers = {'Authorization': f'Bearer {access_token}'} profile_response = requests.get(profile_url, headers=headers) profile_data = profile_response.json() # 获取邮箱(如果申请了r_emailaddress权限) email_url = 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))' email_response = requests.get(email_url, headers=headers) email_data = email_response.json() return {**profile_data, 'email': email_data['elements'][0]['handle~']['emailAddress']}
关键注意事项
- PKCE必须启用:LinkedIn官方要求前端发起的授权流程必须使用PKCE,否则会被拒绝。
- Redirect URI一致性:前端、后端、LinkedIn开发者后台配置的redirect_uri必须完全一致,包括HTTP/HTTPS和端口。
- Client Secret保密:绝对不能把Client Secret放在前端代码里,只能在后端使用。
- 权限申请:确保在LinkedIn开发者后台申请了所需的权限(比如
r_liteprofile、r_emailaddress),否则会拿不到对应的数据。
这个方案完全符合LinkedIn的官方OAuth2规范,解决了前端令牌无法后端使用的问题,同时保证了数据获取的安全性(后端校验授权码,避免前端伪造数据)。
内容的提问来源于stack exchange,提问作者Lucas Basquerotto
相关产品推荐
相关产品推荐

