NextJS 13中FB.login无响应问题求助
解决Next.js 13中Facebook登录FB.login无响应及获取accessToken的问题
一、修复当前FB.login无响应的问题
你的代码存在两个核心问题:
- FB.init时机错误:每次点击按钮才初始化SDK,会导致SDK未完成初始化就调用FB.login,或重复初始化引发冲突,应该在组件加载时完成初始化。
- Promise封装错误:
new Promise(() => {window.FB.login})未正确传递回调resolve结果,导致Promise永远处于pending状态。
修正后的代码(使用Next.js Script组件)
import Script from 'next/script'; import Image from 'next/image'; import { useState } from 'react'; const LoginPage = () => { const [loading, setLoading] = useState(false); // 提前初始化FB SDK,避免重复执行 const initFbSdk = () => { if (window.FB) return; window.fbAsyncInit = function() { window.FB.init({ appId : '你的FB_APP_ID', status : true, cookie : true, xfbml : true, version : 'v16.0' }); }; }; const facebookLoginButton = async (event) => { event.preventDefault(); if (!window.FB) { console.error('FB SDK未加载完成'); return; } setLoading(true); try { // 正确封装FB.login为Promise const authResponse = await new Promise((resolve, reject) => { window.FB.login((response) => { if (response.authResponse) { resolve(response.authResponse); } else { reject(new Error('用户取消登录或授权失败')); } }, { scope: 'public_profile,email' }); // 按需添加所需权限 }); console.log('Facebook Auth响应:', authResponse); // 将accessToken传给后端 // fetch('/api/facebook-login', { // method: 'POST', // body: JSON.stringify({ accessToken: authResponse.accessToken }) // }) } catch (error) { console.error('登录失败:', error); } finally { setLoading(false); } }; return ( <div> <p>登录方式:</p> <Image src="facebooklogin-button.png" width="300" height="46" onClick={facebookLoginButton} alt="Facebook登录" style={{ cursor: 'pointer' }} /> {/* 加载FB SDK,beforeInteractive确保页面交互前完成加载 */} <Script src="https://connect.facebook.net/en_US/sdk.js" strategy="beforeInteractive" onLoad={initFbSdk} // SDK加载完成后执行初始化 /> </div> ); }; export default LoginPage;
二、使用Next-Auth实现Facebook登录并获取accessToken
Next-Auth是更可靠的方案,它简化了社交登录流程,同时支持获取第三方平台的accessToken,配置如下:
1. 安装依赖
npm install next-auth # 或 yarn add next-auth
2. 创建Next-Auth配置文件(app/api/auth/[...nextauth]/route.js)
import NextAuth from "next-auth"; import FacebookProvider from "next-auth/providers/facebook"; export const authOptions = { providers: [ FacebookProvider({ clientId: process.env.FACEBOOK_CLIENT_ID, clientSecret: process.env.FACEBOOK_CLIENT_SECRET, // 指定需要获取的权限 authorization: { params: { scope: "public_profile,email" } } }), ], callbacks: { // 在JWT回调中保存accessToken async jwt({ token, account }) { if (account) { token.accessToken = account.access_token; token.expiresAt = account.expires_at; } return token; }, // 在会话回调中传递accessToken到前端 async session({ session, token }) { session.user.accessToken = token.accessToken; session.user.expiresAt = token.expiresAt; return session; } }, session: { strategy: "jwt" // 必须使用JWT策略才能传递accessToken } }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
3. 在组件中使用登录按钮并获取accessToken
import { signIn, useSession } from "next-auth/react"; import Image from 'next/image'; const LoginPage = () => { const { data: session } = useSession(); if (session) { // 已登录,获取accessToken console.log('Facebook Access Token:', session.user.accessToken); return <div>已登录</div>; } return ( <div> <p>登录方式:</p> <Image src="facebooklogin-button.png" width="300" height="46" onClick={() => signIn('facebook')} alt="Facebook登录" style={{ cursor: 'pointer' }} /> </div> ); }; export default LoginPage;
说明
- Next-Auth会自动处理登录流程,包括跳转Facebook授权页、回调处理等。
- 通过
jwt和session回调,可将Facebook的accessToken传递到前端,之后可发送到后端进行验证或调用Facebook API。
内容的提问来源于stack exchange,提问作者Scottish Smile
相关产品推荐
相关产品推荐

