我使用Firebase + NextJS,在那里我设置了NextAuth和FirestoreAdapter的身份验证。我使用以下allow-all规则进行调试,所有我想要的功能都完美地工作。
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true
}
}
}
字符串
然而,我知道这是一个巨大的安全问题,当我把代码推到生产环境,并希望添加更多的具体规则,只有文档所有者可以读取和写入数据。我已经尝试了这个解决方案从this github issue没有成功。
match /store/{userId}/{document=**} {
allow read, write: if request.auth.token.id == userId && exists(/databases/$(database)/documents/tokens/$(request.auth.uid)/sessions/$(request.auth.token.sessionToken));
}
型
我认为主要的问题来自于nextAuth和FirestoreAdapter与我的Firestore数据库交互的方式。当我使用下面的代码创建一个新文档时,它会按照下面的截图在“users → www.example.com → chats → document”中创建文档session.user.id
是否有适当的方法来设置安全规则,以便只有在session.user.id == chatDoc.userId时才允许DB读/写?
x1c 0d1x的数据
创建新草图
const createNewDraft = async () => {
const doc = await addDoc(
collection(db, "users", session?.user?.id!, "drafts"),
{
userId: session?.user?.id!,
createdAt: serverTimestamp(),
}
);
};
型
[. nextAuth].ts
import { FirestoreAdapter } from "@next-auth/firebase-adapter";
import { GoogleAuthProvider, signInWithCredential } from "firebase/auth";
import { cert } from "firebase-admin/app";
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import "firebase/firestore";
import { fbAuth } from "../../../../firebase";
const sa = JSON.parse(process.env.NEXT_PUBLIC_FIREBASE_SERVICE_KEY);
export const authOptions = {
providers: [
GoogleProvider({
clientId: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID!,
clientSecret: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_SECRET!,
}),
],
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
try {
const googleCredential = GoogleAuthProvider.credential(
account?.id_token
);
const userCredential = await signInWithCredential(
fbAuth,
googleCredential
).catch((e) => {
console.log(e);
return false;
});
return !!userCredential;
} catch (e) {
console.log(e);
return false;
}
},
session: async ({ session, token }) => {
if (session?.user) {
session.user.id = token.sub;
}
return session;
},
},
session: {
strategy: "jwt",
},
adapter: FirestoreAdapter({
credential: cert({
projectId: sa.project_id,
clientEmail: sa.client_email,
privateKey: sa.private_key,
}),
}),
};
export default NextAuth(authOptions);
型
1条答案
按热度按时间gcuhipw91#
我也面临着同样的问题,因为出于明显的安全原因,没有办法将用户会话传递给Firebase安全规则。
经过一番研究,我找到了两种可能的解决方案。
(1)使用Firebase Admin SDK从服务器端结构化所有数据库CRUD访问,因为Firebase管理员绕过所有安全规则,然后您可以将数据库读写设置为false以保护所有其他访问。这种结构现在可以使用NextJS app router,其中默认服务器组件,并使用server actions在客户端组件上执行服务器端操作。
(2)使用Firebase Auth的
signInWithCustomToken()
方法通过从NextAuth传递用户会话来登录Firebase Auth。这需要从现有的NextAuth设置中额外增加2个步骤。使用Firebase管理员的
createCustomToken()
从API路由创建自定义令牌(应用程序路由器示例)。字符串
获得自定义令牌后,在客户端使用
signInWithCustomToken()
登录Firebase Auth。型
一旦用户会话注册到Firebase,您的数据库安全规则就应该按预期工作。
您可以参考此post以进行进一步的阅读。