Firebase Data Connect, क्लाइंट-साइड की मज़बूत सुरक्षा उपलब्ध कराता है. इसके लिए, ये सुविधाएं इस्तेमाल की जाती हैं:
- मोबाइल और वेब क्लाइंट को अनुमति देना
- अलग-अलग क्वेरी और म्यूटेशन के लेवल पर अनुमति देने के कंट्रोल
- Firebase App Check के साथ ऐप्लिकेशन की पुष्टि.
Data Connect इस सुरक्षा को इनके साथ बढ़ाता है:
- सर्वर साइड से अनुमति
- IAM की मदद से, Firebase प्रोजेक्ट और Cloud SQL उपयोगकर्ता की सुरक्षा.
क्लाइंट क्वेरी और म्यूटेशन को अनुमति देना
Data Connect, Firebase Authentication के साथ पूरी तरह से इंटिग्रेट है. इसलिए, आपके पास अपने डिज़ाइन में, उन उपयोगकर्ताओं के बारे में रिच डेटा का इस्तेमाल करने का विकल्प है जो आपके डेटा को ऐक्सेस कर रहे हैं (पुष्टि). इससे यह तय किया जा सकता है कि वे उपयोगकर्ता कौनसा डेटा ऐक्सेस कर सकते हैं (अनुमति).
Data Connect, क्वेरी और बदलावों के लिए @auth
डायरेक्टिव उपलब्ध कराता है. इससे, आपको ऑपरेशन को अनुमति देने के लिए, पुष्टि के लेवल को सेट करने में मदद मिलती है. इस गाइड में, उदाहरण के साथ @auth
डायरेक्टिव के बारे में बताया गया है.
इसके अलावा, Data Connect, बदलावों में एम्बेड की गई क्वेरी को लागू करने की सुविधा देता है. इससे, अनुमति से जुड़ी अन्य शर्तें वापस पाई जा सकती हैं, जिन्हें आपने अपने डेटाबेस में सेव किया है. साथ ही, @check
निर्देशों में उन शर्तों का इस्तेमाल करके यह तय किया जा सकता है कि बदलावों को अनुमति दी गई है या नहीं. अनुमति देने के इस मामले में, @redact
डायरेक्टिव की मदद से यह कंट्रोल किया जा सकता है कि क्वेरी के नतीजे, क्लाइंट को वायर प्रोटोकॉल में दिखाए जाएं या नहीं. साथ ही, जनरेट किए गए एसडीके में एम्बेड की गई क्वेरी को हटाया जाए या नहीं. उदाहरण के साथ, इन निर्देशों के बारे में जानकारी पाएं.
@auth
निर्देश को समझना
@auth
डायरेक्टिव को पैरामीटराइज़ करके, ऐक्सेस के कई प्रीसेट लेवल में से किसी एक का पालन किया जा सकता है. ये लेवल, ऐक्सेस के कई सामान्य मामलों को कवर करते हैं. ये लेवल, PUBLIC
से लेकर NO_ACCESS
तक के होते हैं. PUBLIC
लेवल पर, किसी भी तरह की पुष्टि किए बिना सभी क्लाइंट से क्वेरी और म्यूटेशन की अनुमति होती है. वहीं, NO_ACCESS
लेवल पर, Firebase Admin SDK का इस्तेमाल करने वाले प्रिविलेज्ड सर्वर एनवायरमेंट के बाहर क्वेरी और म्यूटेशन की अनुमति नहीं होती. इनमें से हर लेवल, Firebase Authentication की ओर से दिए गए पुष्टि करने के फ़्लो से जुड़ा होता है.
लेवल | परिभाषा |
---|---|
PUBLIC |
पुष्टि करने के बाद या बिना पुष्टि किए, कोई भी व्यक्ति यह कार्रवाई कर सकता है. |
PUBLIC |
पुष्टि करने के बाद या बिना पुष्टि किए, कोई भी व्यक्ति यह कार्रवाई कर सकता है. |
USER_ANON |
पहचाने गए किसी भी उपयोगकर्ता को क्वेरी या म्यूटेशन करने की अनुमति होती है. इसमें, Firebase Authentication का इस्तेमाल करके गुमनाम रूप से लॉग इन करने वाले उपयोगकर्ता भी शामिल हैं. |
USER |
Firebase Authentication से लॉग इन करने वाले किसी भी उपयोगकर्ता के पास, क्वेरी या म्यूटेशन करने की अनुमति होती है. हालांकि, पहचान छिपाकर साइन इन करने वाले उपयोगकर्ताओं के पास यह अनुमति नहीं होती. |
USER_EMAIL_VERIFIED |
पुष्टि किए गए ईमेल पते के साथ Firebase Authentication से लॉग इन करने वाले किसी भी उपयोगकर्ता को क्वेरी या म्यूटेशन करने की अनुमति होती है. |
NO_ACCESS |
यह कार्रवाई, एडमिन SDK टूल के कॉन्टेक्स्ट के बाहर नहीं की जा सकती. |
इन पहले से तय ऐक्सेस लेवल का इस्तेमाल शुरुआती बिंदु के तौर पर करके, @auth
डायरेक्टिव में अनुमति की जटिल और बेहतर जांच की जा सकती है. इसके लिए, where
फ़िल्टर और सर्वर पर जांचे गए कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) एक्सप्रेशन का इस्तेमाल किया जा सकता है.
अनुमति से जुड़ी सामान्य स्थितियों को लागू करने के लिए, @auth
डायरेक्टिव का इस्तेमाल करना
पहले से तय किए गए ऐक्सेस लेवल, अनुमति देने के लिए शुरुआती बिंदु हैं.
USER
ऐक्सेस लेवल, शुरुआत करने के लिए सबसे ज़्यादा काम का बेसिक लेवल है.
पूरी तरह से सुरक्षित ऐक्सेस, USER
लेवल के साथ-साथ उन फ़िल्टर और एक्सप्रेशन पर आधारित होगा जो उपयोगकर्ता एट्रिब्यूट, संसाधन एट्रिब्यूट, भूमिकाओं, और अन्य जांच की पुष्टि करते हैं. USER_ANON
और USER_EMAIL_VERIFIED
लेवल, USER
केस के वैरिएशन हैं.
एक्सप्रेशन सिंटैक्स की मदद से, auth
ऑब्जेक्ट का इस्तेमाल करके डेटा का आकलन किया जा सकता है. यह ऑब्जेक्ट, ऑपरेशन के साथ पास किए गए पुष्टि करने वाले डेटा को दिखाता है. इसमें, पुष्टि करने वाले टोक़न में मौजूद स्टैंडर्ड डेटा और टोक़न में मौजूद कस्टम डेटा, दोनों शामिल होते हैं. auth
ऑब्जेक्ट में उपलब्ध फ़ील्ड की सूची के लिए, रेफ़रंस सेक्शन देखें.
हालांकि, कुछ मामलों में PUBLIC
सही ऐक्सेस लेवल होता है. हम फिर से बताना चाहते हैं कि ऐक्सेस लेवल हमेशा शुरुआती कदम होता है. बेहतर सुरक्षा के लिए, ज़्यादा फ़िल्टर और एक्सप्रेशन की ज़रूरत होती है.
इस गाइड में अब USER
और PUBLIC
पर बनाने का तरीका बताया गया है.
प्रेरणा देने वाला उदाहरण
सबसे सही तरीके के इन उदाहरणों में, ब्लॉगिंग प्लैटफ़ॉर्म के लिए दिए गए स्कीमा के बारे में बताया गया है. इस प्लैटफ़ॉर्म पर कुछ कॉन्टेंट को ऐक्सेस करने के लिए, पेमेंट प्लान की ज़रूरत होती है.
ऐसे प्लैटफ़ॉर्म पर, Users
औरPosts
का मॉडल बनाया जा सकता है.
type User @table(key: "uid") {
uid: String!
name: String
birthday: Date
createdAt: Timestamp! @default(expr: "request.time")
}
type Post @table {
author: User!
text: String!
# "one of 'draft', 'public', or 'pro'"
visibility: String! @default(value: "draft")
# "the time at which the post should be considered published. defaults to
# immediately"
publishedAt: Timestamp! @default(expr: "request.time")
createdAt: Timestamp! @default(expr: "request.time")
updatedAt: Timestamp! @default(expr: "request.time")
}
उपयोगकर्ता के मालिकाना हक वाले संसाधन
Firebase का सुझाव है कि आप ऐसे फ़िल्टर और एक्सप्रेशन लिखें जिनसे किसी संसाधन के उपयोगकर्ता के मालिकाना हक की जांच की जा सके. यहां दिए गए उदाहरणों में, Posts
के मालिकाना हक की जांच की जा रही है.
नीचे दिए गए उदाहरणों में, एक्सप्रेशन का इस्तेमाल करके पुष्टि करने वाले टोकन का डेटा पढ़ा और उसकी तुलना की गई है. आम तौर पर, सेव किए गए authorUid
की तुलना पुष्टि करने वाले टोकन में पास किए गए auth.uid
(उपयोगकर्ता आईडी) से करने के लिए, where: {authorUid:
{eq_expr: "auth.uid"}}
जैसे एक्सप्रेशन का इस्तेमाल किया जाता है.
बनाएं
अनुमति देने का यह तरीका, पुष्टि करने वाले टोकन से auth.uid
को हर नए Post
में authorUid
फ़ील्ड के तौर पर जोड़कर शुरू होता है, ताकि अनुमति देने के बाद होने वाले टेस्ट में तुलना की जा सके.
# Create a new post as the current user
mutation CreatePost($text: String!, $visibility: String) @auth(level: USER) {
post_insert(data: {
# set the author's uid to the current user uid
authorUid_expr: "auth.uid"
text: $text
visibility: $visibility
})
}
अपडेट करें
जब कोई क्लाइंट किसी Post
को अपडेट करने की कोशिश करता है, तो सेव किए गए authorUid
के मुकाबले, पास किए गए auth.uid
की जांच की जा सकती है.
# Update one of the current user's posts
mutation UpdatePost($id: UUID!, $text: String, $visibility: String) @auth(level:USER) {
post_update(
# only update posts whose author is the current user
first: { where: {
id: {eq: $id}
authorUid: {eq_expr: "auth.uid"}
}}
data: {
text: $text
visibility: $visibility
# insert the current server time for updatedAt
updatedAt_expr: "request.time"
}
)
}
मिटाएं
मिटाने की कार्रवाइयों को अनुमति देने के लिए भी इसी तकनीक का इस्तेमाल किया जाता है.
# Delete one of the current user's posts
mutation DeletePost($id: UUID!) @auth(level: USER) {
post_delete(
# only delete posts whose author is the current user
first: { where: {
id: {eq: $id}
authorUid: {eq_expr: "auth.uid"}
}}
)
}
# Common display information for a post
fragment DisplayPost on Post {
id, text, createdAt, updatedAt
author { uid, name }
}
सूची
# List all posts belonging to the current user
query ListMyPosts @auth(level: USER) {
posts(where: {
userUid: {eq_expr: "auth.uid"}
}) {
# See the fragment above
...DisplayPost
# also show visibility since it is user-controlled
visibility
}
}
पाएं
# Get a post only if it belongs to the current user
query GetMyPost($id: UUID!) @auth(level: USER) {
post(key: {id: $id},
first: {where: {
id: {eq: $id}
authorUid: {eq_expr: "auth.uid"}}
}}, {
# See the fragment above
...DisplayPost
# also show visibility since it is user-controlled
visibility
}
}
डेटा फ़िल्टर करना
Data Connect के अनुमति देने वाले सिस्टम की मदद से, बेहतर फ़िल्टर लिखे जा सकते हैं. इन फ़िल्टर में, PUBLIC
जैसे पहले से तय किए गए ऐक्सेस लेवल के साथ-साथ, पुष्टि करने वाले टोकन का डेटा भी इस्तेमाल किया जा सकता है.
अनुमति देने वाले सिस्टम की मदद से, सिर्फ़ एक्सप्रेशन का इस्तेमाल किया जा सकता है. इसके लिए, आपको बुनियादी ऐक्सेस लेवल की ज़रूरत नहीं होती. इसका उदाहरण नीचे दिए गए कुछ उदाहरणों में दिया गया है.
रिसॉर्स एट्रिब्यूट के हिसाब से फ़िल्टर करना
यहां अनुमति, पुष्टि करने वाले टोकन के आधार पर नहीं दी जाती, क्योंकि सुरक्षा का बुनियादी लेवल PUBLIC
पर सेट है. हालांकि, हम अपने डेटाबेस में रिकॉर्ड को साफ़ तौर पर, सार्वजनिक ऐक्सेस के लिए सेट कर सकते हैं. मान लें कि हमारे डेटाबेस में Post
रिकॉर्ड हैं और visibility
को "सार्वजनिक" पर सेट किया गया है.
# List all posts marked as 'public' visibility
query ListPublicPosts @auth(level: PUBLIC) {
posts(where: {
# Test that visibility is "public"
visibility: {eq: "public"}
# Only display articles that are already published
publishedAt: {lt_expr: "request.time"}
}) {
# see the fragment above
...DisplayPost
}
}
उपयोगकर्ता के दावों के हिसाब से फ़िल्टर करना
यहां मान लें कि आपने उपयोगकर्ता के ऐसे कस्टम दावे सेट अप किए हैं जो पुष्टि करने वाले टोकन में पास किए जाते हैं. इन दावों की मदद से, आपके ऐप्लिकेशन के "प्रॉ" प्लान में उपयोगकर्ताओं की पहचान की जाती है. ये दावे, पुष्टि करने वाले टोकन में auth.token.plan
फ़ील्ड के साथ फ़्लैग किए जाते हैं. आपके एक्सप्रेशन इस फ़ील्ड के हिसाब से जांचे जा सकते हैं.
# List all public or pro posts, only permitted if user has "pro" plan claim
query ProListPosts @auth(expr: "auth.token.plan == 'pro'") {
posts(where: {
# display both public posts and "pro" posts
visibility: {in: ['public', 'pro']},
# only display articles that are already published
publishedAt: {lt_expr: "request.time"},
}) {
# see the fragment above
...DisplayPost
# show visibility so pro users can see which posts are pro\
visibility
}
}
क्रम और सीमा के हिसाब से फ़िल्टर करना
इसके अलावा, हो सकता है कि आपने Post
रिकॉर्ड में visibility
सेट किया हो, ताकि यह पता चल सके कि वे "प्रॉफ़ेशनल" उपयोगकर्ताओं के लिए उपलब्ध कॉन्टेंट हैं. हालांकि, डेटा की झलक या टीज़र लिस्टिंग के लिए, रिकॉर्ड की संख्या को और सीमित करें.
# Show 2 oldest Pro post as a preview
query ProTeaser @auth(level: USER) {
posts(
where: {
# show only pro posts
visibility: {eq: "pro"}
# that have already been published more than 30 days ago
publishedAt: {lt_time: {now: true, sub: {days: 30}}}
},
# order by publish time
orderBy: [{publishedAt: DESC}],
# only return two posts
limit: 2
) {
# See the fragment above
...DisplayPost
}
}
भूमिका के हिसाब से फ़िल्टर करना
अगर आपके कस्टम दावे में admin
भूमिका तय की गई है, तो आपके पास इसके हिसाब से कार्रवाइयों की जांच करने और उन्हें अनुमति देने का विकल्प होता है.
# List all posts unconditionally iff the current user has an admin claim
query AdminListPosts @auth(expr: "auth.token.admin == true") {
posts { ...DisplayPost }
}
@check
और @redact
डायरेक्टिव को समझना
@check
डायरेक्टिव यह पुष्टि करता है कि क्वेरी के नतीजों में, तय किए गए फ़ील्ड मौजूद हैं. फ़ील्ड वैल्यू की जांच करने के लिए, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) एक्सप्रेशन का इस्तेमाल किया जाता है. डायरेक्टिव का डिफ़ॉल्ट तरीका, null
वैल्यू वाले नोड की जांच करना और उन्हें अस्वीकार करना है.
@redact
डायरेक्टिव, क्लाइंट के रिस्पॉन्स के किसी हिस्से को छिपाता है. हटाए गए फ़ील्ड का आकलन अब भी साइड इफ़ेक्ट के लिए किया जाता है. इनमें डेटा में हुए बदलाव और @check
भी शामिल हैं. साथ ही, सीईएल एक्सप्रेशन के बाद के चरणों में भी ये नतीजे उपलब्ध होते हैं.
Data Connect में, @check
और @redact
निर्देशों का इस्तेमाल अक्सर अनुमति की जांच के संदर्भ में किया जाता है. ज़्यादा जानकारी के लिए, अनुमति के डेटा लुकअप की चर्चा देखें.
अनुमति का डेटा देखने के लिए, @check
और @redact
निर्देश जोड़ें
अनुमति के इस्तेमाल के सामान्य उदाहरण में, आपके डेटाबेस में अनुमति की कस्टम भूमिकाएं सेव करना शामिल है. उदाहरण के लिए, खास अनुमतियों वाली टेबल में. साथ ही, डेटा बनाने, अपडेट करने या मिटाने के लिए, म्यूटेशन की अनुमति देने के लिए उन भूमिकाओं का इस्तेमाल करना.
अनुमति वाले डेटा लुकअप का इस्तेमाल करके, userID के आधार पर भूमिकाओं के लिए क्वेरी की जा सकती है. साथ ही, बदलाव की अनुमति है या नहीं, यह तय करने के लिए सीईएल एक्सप्रेशन का इस्तेमाल किया जा सकता है. उदाहरण के लिए, हो सकता है कि आपको ऐसा UpdateMovieTitle
म्यूटेशन लिखना हो जिससे अनुमति पा चुके क्लाइंट, फ़िल्म के टाइटल अपडेट कर सकें.
इस चर्चा के बाकी हिस्से के लिए, मान लें कि फ़िल्म की समीक्षा करने वाले ऐप्लिकेशन का डेटाबेस, अनुमति देने वाली भूमिका को MoviePermission
टेबल में सेव करता है.
# MoviePermission
# Suppose a user has an authorization role with respect to records in the Movie table
type MoviePermission @table(key: ["doc", "userId"]) {
movie: Movie! # implies another field: movieId: UUID!
userId: String! # Can also be a reference to a User table, doesn't matter
role: String!
}
नीचे दिए गए उदाहरण में, UpdateMovieTitle
म्यूटेशन में MoviePermission
से डेटा पाने के लिए query
फ़ील्ड शामिल है. साथ ही, यह पक्का करने के लिए ये निर्देश भी शामिल हैं कि ऑपरेशन सुरक्षित और मज़बूत हो:
@transaction
डायरेक्टिव, जिससे यह पक्का किया जा सके कि अनुमति से जुड़ी सभी क्वेरी और जांच पूरी हो गई हों या एक साथ पूरी न हुई हों.- रिस्पॉन्स से क्वेरी के नतीजे हटाने के लिए
@redact
डायरेक्टिव. इसका मतलब है कि अनुमति की जांच Data Connect सर्वर पर की जाती है, लेकिन संवेदनशील डेटा को क्लाइंट को नहीं दिखाया जाता. क्वेरी के नतीजों पर अनुमति के लॉजिक का आकलन करने के लिए,
@check
निर्देशों का एक जोड़ा. जैसे, यह जांच करना कि किसी दिए गए userID के पास बदलाव करने के लिए सही भूमिका है या नहीं.
mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
# Step 1: Query and check
query @redact {
moviePermission( # Look up a join table called MoviePermission with a compound key.
key: {movieId: $movieId, userId_expr: "auth.uid"}
# Step 1a: Use @check to test if the user has any role associated with the movie
# Here the `this` binding refers the lookup result, i.e. a MoviePermission object or null
# The `this != null` expression could be omitted since rejecting on null is default behavior
) @check(expr: "this != null", message: "You do not have access to this movie") {
# Step 1b: Check if the user has the editor role for the movie
# Next we execute another @check; now `this` refers to the contents of the `role` field
role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
}
}
# Step 2: Act
movie_update(id: $movieId, data: {
title: $newTitle
})
}
अनुमति देने के दौरान, इन गलत तरीकों से बचना
पिछले सेक्शन में, @auth
निर्देश का इस्तेमाल करते समय अपनाए जाने वाले पैटर्न के बारे में बताया गया है.
आपको उन ज़रूरी एंटीपैटर्न के बारे में भी पता होना चाहिए जिनसे बचना है.
क्वेरी और म्यूटेशन आर्ग्युमेंट में, उपयोगकर्ता एट्रिब्यूट आईडी और पुष्टि करने वाले टोकन पैरामीटर पास करने से बचें
Firebase Authentication, पुष्टि करने के फ़्लो को दिखाने और पुष्टि करने से जुड़े डेटा को सुरक्षित तरीके से कैप्चर करने के लिए एक बेहतरीन टूल है. जैसे, रजिस्टर किए गए उपयोगकर्ता आईडी और पुष्टि करने वाले टोकन में सेव किए गए कई फ़ील्ड.
क्वेरी और म्यूटेशन आर्ग्युमेंट में उपयोगकर्ता आईडी और पुष्टि करने वाले टोकन का डेटा पास करने का सुझाव नहीं दिया जाता.
# Antipattern!
# This incorrectly allows any user to view any other user's posts
query AllMyPosts($userId: String!) @auth(level: USER) {
posts(where: {authorUid: {eq: $userId}}) {
id, text, createdAt
}
}
बिना किसी फ़िल्टर के USER
ऐक्सेस लेवल का इस्तेमाल करने से बचें
जैसा कि गाइड में कई बार बताया गया है, USER
,
USER_ANON
, USER_EMAIL_VERIFIED
जैसे मुख्य ऐक्सेस लेवल, अनुमति की जांच के लिए आधारभूत और शुरुआती पॉइंट होते हैं. इन्हें फ़िल्टर और एक्सप्रेशन की मदद से बेहतर बनाया जा सकता है. कौन उपयोगकर्ता अनुरोध कर रहा है, यह जांच करने वाले फ़िल्टर या एक्सप्रेशन के बिना इन लेवल का इस्तेमाल करना, PUBLIC
लेवल का इस्तेमाल करने के बराबर है.
# Antipattern!
# This incorrectly allows any user to view all documents
query ListDocuments @auth(level: USER) {
documents {
id
title
text
}
}
प्रोटोटाइप बनाने के लिए, PUBLIC
या USER
ऐक्सेस लेवल का इस्तेमाल करने से बचें
डेवलपमेंट की प्रोसेस को तेज़ करने के लिए, सभी ऑपरेशन को PUBLIC
ऐक्सेस लेवल या USER
ऐक्सेस लेवल पर सेट किया जा सकता है. ऐसा करने से, सभी ऑपरेशन को अनुमति मिल जाती है और आपको अपने कोड की तुरंत जांच करने में मदद मिलती है.
इस तरह से प्रोटोटाइप बनाने के बाद, NO_ACCESS
से PUBLIC
और USER
लेवल पर, प्रोडक्शन के लिए तैयार अनुमति पर स्विच करें.
हालांकि, इस गाइड में दिखाए गए अतिरिक्त लॉजिक को जोड़े बिना, उन्हें PUBLIC
या USER
के तौर पर डिप्लॉय न करें.
# Antipattern!
# This incorrectly allows anyone to delete any post
mutation DeletePost($id: UUID!) @auth(level: PUBLIC) {
post: post_delete(
id: $id,
)
}
ऐप्लिकेशन की पुष्टि करने के लिए Firebase App Check का इस्तेमाल करना
पुष्टि और अनुमति, Data Connect की सुरक्षा के लिए ज़रूरी हैं. पुष्टि करने और अनुमति देने की सुविधा के साथ-साथ ऐप्लिकेशन की पुष्टि करने की सुविधा, सुरक्षा का एक बहुत ही बेहतरीन समाधान है.
Firebase App Check की मदद से पुष्टि करने पर, आपके ऐप्लिकेशन को चलाने वाले डिवाइस, ऐप्लिकेशन या डिवाइस की पुष्टि करने वाली किसी सेवा का इस्तेमाल करेंगे. यह सेवा पुष्टि करती है कि Data Connect के ऑपरेशन, आपके असली ऐप्लिकेशन से शुरू होते हैं और अनुरोध, असली और बिना छेड़छाड़ किए गए डिवाइस से शुरू होते हैं. यह पुष्टि, Data Connect से किए गए आपके ऐप्लिकेशन के हर अनुरोध के साथ अटैच की जाती है.
Data Connect के लिए App Check को चालू करने और अपने ऐप्लिकेशन में इसके क्लाइंट SDK टूल को शामिल करने का तरीका जानने के लिए, App Check की खास जानकारी देखें.
@auth(level)
डायरेक्टिव के लिए पुष्टि के लेवल
इस टेबल में, ऐक्सेस के सभी स्टैंडर्ड लेवल और उनके सीईएल लेवल की जानकारी दी गई है. पुष्टि करने के लेवल, बड़े से छोटे क्रम में दिए गए हैं -- हर लेवल में उन सभी उपयोगकर्ताओं को शामिल किया जाता है जो इन लेवल से मैच करते हैं.
लेवल | परिभाषा |
---|---|
PUBLIC |
पुष्टि करने के बाद या बिना पुष्टि किए, कोई भी व्यक्ति यह कार्रवाई कर सकता है.
ध्यान देने वाली बातें: डेटा को कोई भी उपयोगकर्ता पढ़ सकता है या उसमें बदलाव कर सकता है. Firebase, सार्वजनिक तौर पर ब्राउज़ किए जा सकने वाले डेटा के लिए, अनुमति के इस लेवल का सुझाव देता है. जैसे, प्रॉडक्ट या मीडिया लिस्टिंग. सबसे सही तरीके के उदाहरण और विकल्प देखें. @auth(expr: "true") के बराबर है
@auth फ़िल्टर और एक्सप्रेशन का इस्तेमाल, इस ऐक्सेस लेवल के साथ नहीं किया जा सकता. ऐसे किसी भी एक्सप्रेशन को 400 गलत
अनुरोध वाली गड़बड़ी के साथ अस्वीकार कर दिया जाएगा.
|
USER_ANON |
पहचाने गए किसी भी उपयोगकर्ता को क्वेरी या म्यूटेशन करने की अनुमति होती है. इसमें, Firebase Authentication का इस्तेमाल करके गुमनाम रूप से लॉग इन करने वाले उपयोगकर्ता भी शामिल हैं.
ध्यान दें: USER_ANON , USER का सुपरसेट है.
ध्यान देने वाली बातें: ध्यान दें कि अनुमति के इस लेवल के लिए, आपको अपनी क्वेरी और म्यूटेशन को ध्यान से डिज़ाइन करना होगा. इस लेवल पर, उपयोगकर्ता को Authentication की मदद से बिना पहचान ज़ाहिर किए (सिर्फ़ उपयोगकर्ता के डिवाइस से जुड़ा ऑटोमैटिक साइन-इन) लॉग इन करने की अनुमति मिलती है. साथ ही, यह अपने-आप कोई और जांच नहीं करता. उदाहरण के लिए, यह जांच नहीं करता कि डेटा उपयोगकर्ता का है या नहीं. सबसे सही तरीके के उदाहरण और विकल्प देखें. पहचान छिपाकर लॉगिन करने वाले Authentication फ़्लो, uid जारी करते हैं. इसलिए,
USER_ANON लेवल,
@auth(expr: "auth.uid != nil") के बराबर है
|
USER |
Firebase Authentication से लॉग इन करने वाले किसी भी उपयोगकर्ता के पास, क्वेरी या म्यूटेशन करने की अनुमति होती है. हालांकि, पहचान छिपाकर साइन इन करने वाले उपयोगकर्ताओं के पास यह अनुमति नहीं होती.
ध्यान देने वाली बातें: ध्यान दें कि अनुमति के इस लेवल के लिए, आपको अपनी क्वेरी और म्यूटेशन को ध्यान से डिज़ाइन करना होगा. यह लेवल सिर्फ़ यह जांच करता है कि उपयोगकर्ता ने Authentication से लॉग इन किया है या नहीं. यह अपने-आप कोई दूसरी जांच नहीं करता. उदाहरण के लिए, यह जांच नहीं करता कि डेटा उपयोगकर्ता का है या नहीं. सबसे सही तरीके के उदाहरण और विकल्प देखें. @auth(expr: "auth.uid != nil &&
auth.token.firebase.sign_in_provider != 'anonymous'")" के बराबर
|
USER_EMAIL_VERIFIED |
पुष्टि किए गए ईमेल पते के साथ Firebase Authentication से लॉग इन करने वाले किसी भी उपयोगकर्ता को क्वेरी या म्यूटेशन करने की अनुमति होती है.
ध्यान देने वाली बातें: ईमेल पते की पुष्टि, Authentication का इस्तेमाल करके की जाती है. यह पुष्टि करने का एक बेहतर तरीका है. इसलिए, यह लेवल USER या USER_ANON की तुलना में ज़्यादा सुरक्षित होता है.Authentication यह लेवल सिर्फ़ यह जांच करता है कि उपयोगकर्ता ने पुष्टि किए गए ईमेल पते से Authentication में लॉग इन किया है या नहीं. यह अपने-आप कोई दूसरी जांच नहीं करता. उदाहरण के लिए, यह जांच नहीं करता कि डेटा उपयोगकर्ता का है या नहीं. सबसे सही तरीके के उदाहरण और विकल्प देखें.
@auth(expr: "auth.uid != nil &&
auth.token.email_verified")" के बराबर |
NO_ACCESS |
यह कार्रवाई, एडमिन SDK टूल के कॉन्टेक्स्ट के बाहर नहीं की जा सकती.
@auth(expr: "false") के बराबर |
@auth(expr)
और @check(expr)
के लिए सीईएल रेफ़रंस
इस गाइड में दिए गए उदाहरणों में दिखाया गया है कि @auth(expr:)
और @check
निर्देशों का इस्तेमाल करके, Data Connect के लिए अनुमति को कंट्रोल करने के लिए, कॉमन एक्सप्रेशन लैंग्वेज (सीईएल) में बताए गए एक्सप्रेशन का इस्तेमाल किया जा सकता है और किया जाना चाहिए.
इस सेक्शन में, इन निर्देशों के लिए एक्सप्रेशन बनाने से जुड़ा सीईएल सिंटैक्स शामिल है.
सीईएल के लिए पूरी रेफ़रंस जानकारी, सीईएल स्पेसिफ़िकेशन में दी गई है.
क्वेरी और म्यूटेशन में पास किए गए वैरिएबल की जांच करना
@auth(expr)
सिंटैक्स की मदद से, क्वेरी और
बदलावों से वैरिएबल ऐक्सेस किए जा सकते हैं और उनकी जांच की जा सकती है.
उदाहरण के लिए, vars.status
का इस्तेमाल करके, $status
जैसे ऑपरेशन वैरिएबल को शामिल किया जा सकता है.
mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")
एक्सप्रेशन के लिए उपलब्ध डेटा
@auth(expr:)
और @check(expr:)
, दोनों सीईएल एक्सप्रेशन इनका आकलन कर सकते हैं:
request.operationName
vars
(request.variables
का उपनाम)auth
(request.auth
का उपनाम)
इसके अलावा, @check(expr:)
एक्सप्रेशन का इस्तेमाल करके इनका आकलन किया जा सकता है:
this
(मौजूदा फ़ील्ड की वैल्यू)
request.operationName ऑब्जेक्ट
request.operarationName
ऑब्जेक्ट, ऑपरेशन का टाइप सेव करता है. यह क्वेरी या म्यूटेशन, दोनों में से कोई एक हो सकता है.
vars
ऑब्जेक्ट
vars
ऑब्जेक्ट की मदद से, आपके एक्सप्रेशन आपकी क्वेरी या म्यूटेशन में पास किए गए सभी वैरिएबल ऐक्सेस कर सकते हैं.
किसी एक्सप्रेशन में, vars.<variablename>
का इस्तेमाल पूरी तरह से तय किए गए request.variables.<variablename>
के लिए, किसी दूसरे नाम के तौर पर किया जा सकता है:
# The following are equivalent
mutation StringType($v: String!) @auth(expr: "vars.v == 'hello'")
mutation StringType($v: String!) @auth(expr: "request.variables.v == 'hello'")
auth
ऑब्जेक्ट
Authentication, आपके डेटा को ऐक्सेस करने का अनुरोध करने वाले उपयोगकर्ताओं की पहचान करता है. साथ ही, उस जानकारी को ऑब्जेक्ट के तौर पर उपलब्ध कराता है, जिसे अपने एक्सप्रेशन में इस्तेमाल किया जा सकता है.
अपने फ़िल्टर और एक्सप्रेशन में, auth
का इस्तेमाल request.auth
के लिए किसी दूसरे नाम के तौर पर किया जा सकता है.
auth ऑब्जेक्ट में यह जानकारी शामिल होती है:
uid
: अनुरोध करने वाले उपयोगकर्ता को असाइन किया गया यूनीक यूज़र आईडी.token
: Authentication से इकट्ठा की गई वैल्यू का मैप.
auth.token
के कॉन्टेंट के बारे में ज़्यादा जानकारी के लिए,
पुष्टि करने वाले टोकन में मौजूद डेटा देखें
this
बाइंडिंग
बाइंडिंग this
उस फ़ील्ड का आकलन करता है जिससे @check
डायरेक्टिव जुड़ा है. सामान्य तौर पर, एक वैल्यू वाली क्वेरी के नतीजों का आकलन किया जा सकता है.
mutation UpdateMovieTitle($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
# Step 1: Query and check
query @redact {
moviePermission( # Look up a join table called MoviePermission with a compound key.
key: {movieId: $movieId, userId_expr: "auth.uid"}
) {
# Check if the user has the editor role for the movie. `this` is the string value of `role`.
# If the parent moviePermission is null, the @check will also fail automatically.
role @check(expr: "this == 'editor'", message: "You must be an editor of this movie to update title")
}
}
# Step 2: Act
movie_update(id: $movieId, data: {
title: $newTitle
})
}
अगर कोई पैरंट फ़ील्ड सूची है, तो रिटर्न किया गया फ़ील्ड कई बार दिख सकता है. ऐसे में, हर वैल्यू के साथ बाउंड किए गए this
की मदद से, हर बार दिखने वाले फ़ील्ड की जांच की जाती है.
किसी भी पाथ के लिए, अगर कोई पैरंट null
या []
है, तो फ़ील्ड तक नहीं पहुंचा जा सकेगा और उस पाथ के लिए सीईएल का आकलन नहीं किया जाएगा. दूसरे शब्दों में, आकलन सिर्फ़ तब होता है, जब this
null
या नॉन-null
हो, लेकिन कभी भी undefined
नहीं.
जब फ़ील्ड खुद ही कोई सूची या ऑब्जेक्ट होता है, तो this
उसी स्ट्रक्चर का पालन करता है (इसमें ऑब्जेक्ट के मामले में चुने गए सभी डिसेंटेंट शामिल होते हैं), जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है.
mutation UpdateMovieTitle2($movieId: UUID!, $newTitle: String!) @auth(level: USER) @transaction {
# Step 1: Query and check
query {
moviePermissions( # Now we query for a list of all matching MoviePermissions.
where: {movieId: {eq: $movieId}, userId: {eq_expr: "auth.uid"}}
# This time we execute the @check on the list, so `this` is the list of objects.
# We can use the `.exists` macro to check if there is at least one matching entry.
) @check(expr: "this.exists(p, p.role == 'editor')", message: "You must be an editor of this movie to update title") {
role
}
}
# Step 2: Act
movie_update(id: $movieId, data: {
title: $newTitle
})
}
कॉम्प्लेक्स एक्सप्रेशन का सिंटैक्स
&&
और ||
ऑपरेटर को मिलाकर, ज़्यादा जटिल एक्सप्रेशन लिखे जा सकते हैं.
mutation UpsertUser($username: String!) @auth(expr: "(auth != null) && (vars.username == 'joe')")
नीचे दिए गए सेक्शन में, सभी उपलब्ध ऑपरेटर के बारे में बताया गया है.
ऑपरेटर और ऑपरेटर की प्राथमिकता
ऑपरेटर और उनके क्रम के रेफ़रंस के लिए, नीचे दी गई टेबल का इस्तेमाल करें.
a
और b
एक्सप्रेशन, f
फ़ील्ड, और i
इंडेक्स.
ऑपरेटर | ब्यौरा | असोसिएटिविटी |
---|---|---|
a[i] a() a.f |
इंडेक्स, कॉल, फ़ील्ड ऐक्सेस | बाएं से दाएं |
!a -a |
एक आर्ग्युमेंट वाला नेगेटिव | दाएं से बाएं |
a/b a%b a*b |
गुणा करने वाले ऑपरेटर | बाएं से दाएं |
a+b a-b |
ऐडिटिव ऑपरेटर | बाएं से दाएं |
a>b a>=b a<b a<=b |
रिलेशनल ऑपरेटर | बाएं से दाएं |
a in b |
सूची या मैप में मौजूद होना | बाएं से दाएं |
type(a) == t |
टाइप की तुलना, जहां t के तौर पर bool, int, float,
number, string, list, map, timestamp या duration का इस्तेमाल किया जा सकता है |
बाएं से दाएं |
a==b a!=b |
कंपैरिज़न ऑपरेटर | बाएं से दाएं |
a && b |
कंडीशनल ऐंड | बाएं से दाएं |
a || b |
कंडीशनल OR | बाएं से दाएं |
a ? true_value : false_value |
तीसरे डिग्री का एक्सप्रेशन | बाएं से दाएं |
पुष्टि करने वाले टोकन में डेटा
auth.token
ऑब्जेक्ट में ये वैल्यू हो सकती हैं:
फ़ील्ड | ब्यौरा |
---|---|
email |
खाते से जुड़ा ईमेल पता, अगर मौजूद हो. |
email_verified |
true , अगर उपयोगकर्ता ने पुष्टि की है कि उसके पास email पते का ऐक्सेस है. ईमेल की सेवा देने वाली कुछ कंपनियां, अपने ईमेल पतों की पुष्टि अपने-आप करती हैं. |
phone_number |
खाते से जुड़ा फ़ोन नंबर, अगर मौजूद हो. |
name |
अगर सेट किया गया है, तो उपयोगकर्ता का डिसप्ले नेम. |
sub |
उपयोगकर्ता का Firebase यूआईडी. यह किसी प्रोजेक्ट में यूनीक होता है. |
firebase.identities |
इस उपयोगकर्ता के खाते से जुड़ी सभी पहचानों की डिक्शनरी. डिक्शनरी की कुंजियां इनमें से कोई भी हो सकती हैं: email , phone , google.com , facebook.com , github.com , twitter.com . डिक्शनरी की वैल्यू, खाते से जुड़े हर आइडेंटिटी प्रोवाइडर के लिए यूनीक आइडेंटिफ़ायर के कलेक्शन होती हैं. उदाहरण के लिए, auth.token.firebase.identities["google.com"][0] में खाते से जुड़ा पहला Google उपयोगकर्ता आईडी होता है. |
firebase.sign_in_provider |
इस टोकन को पाने के लिए, साइन इन करने की सुविधा देने वाली कंपनी. यह इनमें से कोई एक स्ट्रिंग हो सकती है: custom , password , phone , anonymous , google.com , facebook.com , github.com , twitter.com . |
firebase.tenant |
खाते से जुड़ा tenantId, अगर मौजूद हो. उदाहरण के लिए, tenant2-m6tyz |
JWT आईडी टोकन में अतिरिक्त फ़ील्ड
यहां दिए गए auth.token
फ़ील्ड भी ऐक्सेस किए जा सकते हैं:
कस्टम टोकन पर दावे | ||
---|---|---|
alg |
एल्गोरिदम | "RS256" |
iss |
जारी करने वाला | आपके प्रोजेक्ट के सेवा खाते का ईमेल पता |
sub |
विषय | आपके प्रोजेक्ट के सेवा खाते का ईमेल पता |
aud |
ऑडियंस | "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit" |
iat |
जारी करने का समय | यूनिक्स के टाइमस्टैंप के बाद से, सेकंड में मौजूदा समय |
exp |
समाप्ति समय |
यूनिक्स के टाइमस्टैंप के बाद सेकंड में, टोकन की समयसीमा खत्म होने का समय. यह iat के मुकाबले ज़्यादा से ज़्यादा 3600 सेकंड बाद हो सकता है.
ध्यान दें: इससे सिर्फ़ कस्टम टोकन के खत्म होने का समय कंट्रोल होता है. हालांकि, signInWithCustomToken() का इस्तेमाल करके किसी उपयोगकर्ता को साइन इन करने के बाद, वह डिवाइस में तब तक साइन इन रहेगा, जब तक उसका सेशन अमान्य नहीं हो जाता या वह साइन आउट नहीं कर देता.
|
<claims> (ज़रूरी नहीं) |
टोकन में शामिल करने के लिए, ज़रूरी नहीं कि कस्टम दावे किए जाएं. इन्हें एक्सप्रेशन में
auth.token (या request.auth.token ) के ज़रिए ऐक्सेस किया जा सकता है. उदाहरण के लिए, अगर आपने कोई कस्टम दावा
adminClaim किया है, तो उसे
auth.token.adminClaim से ऐक्सेस किया जा सकता है.
|
आगे क्या करना है?
- Firebase Data Connect, एडमिन SDK टूल उपलब्ध कराता है, ताकि आप खास एनवायरमेंट से क्वेरी और म्यूटेशन कर सकें.
- सेवाओं और डेटाबेस को मैनेज करने के लिए गाइड में, IAM की सुरक्षा के बारे में जानें.