我正在尝试学习如何使用 firebase 对我的 nextjs 应用程序实施身份验证。使用 Firebase 时我们要做的第一件事是使用我们的配置初始化 Firebase(
apiKey
等)。如果我使用客户端组件中的任何 firebase 函数,它需要将此配置发送到客户端,我认为这是我们永远不应该做的事情?
https://firebase.google.com/codelabs/firebase-nextjs#5 但在谷歌的这个教程中他们就是这样做的吗?他们在
.env
变量前加上 NEXT_PUBLIC_
前缀,这使得它们可用于客户端组件?像谷歌这样的公司会为他们的产品创建错误的教程吗?可以发送我的 firebase conf.conf 吗?给客户?
如果不是,我如何使用服务器组件实现此功能。我认为对于登录和注销,我可以调用服务器操作吗?
我不能做的是如何监听身份验证状态并根据该状态呈现 UI(将登录按钮更改为注销按钮等)
假设我有服务器组件导航栏:
function Navbar() {
let signedIn = false;
auth.onAuthStateChanged((authUser) => {
if (authUser) {
signedIn = true;
}
});
return (
signedIn ? <SignOutButton /> : <SignInButton />
)
}
我无法在服务器组件上使用 state 或 useEffect 并且我不知道像这样声明普通变量是否合适?
请看下面
这就是典型的配置。文件看起来像
import firebase from 'firebase/app';
import 'firebase/auth';
const firebaseConfig = {
apiKey: 'YOUR_API_KEY',
authDomain: 'YOUR_AUTH_DOMAIN',
projectId: 'YOUR_PROJECT_ID',
storageBucket: 'YOUR_STORAGE_BUCKET',
messagingSenderId: 'YOUR_MESSAGING_SENDER_ID',
appId: 'YOUR_APP_ID',
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
您一定最担心的是向公众公开 API 密钥。因此请阅读下文
Firebase 的 API 密钥与典型 API 密钥不同
与 API 密钥的通常使用方式不同,Firebase 服务的 API 密钥 不用于控制对后端资源的访问;那只能是 使用Firebase安全规则完成(控制哪些用户可以访问 资源)和应用程序检查(控制哪些应用程序可以访问资源)。
通常,您需要严格保护 API 密钥(例如,通过 使用保管库服务或将密钥设置为环境变量); 但是,Firebase 服务的 API 密钥可以包含在代码中或 签入配置文件。
尽管 Firebase 服务的 API 密钥可以安全地包含在代码中, 在某些特定情况下,您应该对您的设备实施限制 API 密钥;例如,如果您使用 Firebase ML,则 Firebase 使用电子邮件/密码登录方法或计费方式进行身份验证 谷歌云API。稍后在本页了解有关这些案例的更多信息。
如果您清楚 Firebase 项目中 API 密钥的使用和工作方式,那么您可以照常遵循其余的暗示
例如:
用于使用Google登录:
const signInWithGoogle = async () => {
const provider = new firebase.auth.GoogleAuthProvider();
await firebase.auth().signInWithPopup(provider);
};
现在的目的是确保用户的身份验证状态(如您突出显示的)。您可以使用订阅状态来进行身份验证更改 要订阅身份验证更改,请按照以下步骤操作:
导航到 src/components/Header.jsx 文件。 将 useUserSession 函数替换为以下代码:
function useUserSession(initialUser) {
// The initialUser comes from the server through a server component
const [user, setUser] = useState(initialUser);
const router = useRouter();
useEffect(() => {
const unsubscribe = onAuthStateChanged(authUser => {
setUser(authUser);
});
return () => {
unsubscribe();
};
}, []);
useEffect(() => {
onAuthStateChanged(authUser => {
if (user === undefined) return;
if (user?.email !== authUser?.email) {
router.refresh();
}
});
}, [user]);
return user;
}
有关更多详细信息,请访问参考:firebase-nextjs#5