เชื่อมต่อข้อมูลอย่างปลอดภัยด้วยการให้สิทธิ์และการรับรอง

Firebase Data Connect มอบการรักษาความปลอดภัยฝั่งไคลเอ็นต์ที่รัดกุมด้วยสิ่งต่อไปนี้

  • การให้สิทธิ์ไคลเอ็นต์บนอุปกรณ์เคลื่อนที่และเว็บ
  • การควบคุมการให้สิทธิ์ระดับการค้นหาและการเปลี่ยนแปลงแต่ละรายการ
  • การรับรองแอปด้วย Firebase App Check

Data Connect ขยายการรักษาความปลอดภัยนี้ด้วยสิ่งต่อไปนี้

  • การให้สิทธิ์ฝั่งเซิร์ฟเวอร์
  • ความปลอดภัยของโปรเจ็กต์ Firebase และผู้ใช้ Cloud SQL ด้วย IAM

ให้สิทธิ์การค้นหาและการเปลี่ยนแปลงของไคลเอ็นต์

Data Connect ผสานรวมกับ Firebase Authentication อย่างเต็มรูปแบบ คุณจึงใช้ข้อมูลที่สมบูรณ์เกี่ยวกับผู้ใช้ที่เข้าถึงข้อมูลของคุณ (การตรวจสอบสิทธิ์) ในการออกแบบข้อมูลที่ผู้ใช้เหล่านั้นเข้าถึงได้ (การให้สิทธิ์)

Data Connect มีคำสั่ง @auth สำหรับการค้นหาและการเปลี่ยนแปลงที่ช่วยให้คุณกำหนดระดับการตรวจสอบสิทธิ์ที่จำเป็นในการให้สิทธิ์การดำเนินการได้ คู่มือนี้จะแนะนำเกี่ยวกับคำสั่ง @auth พร้อมตัวอย่าง

นอกจากนี้ Data Connect ยังรองรับการดำเนินการของคําค้นหาที่ฝังอยู่ใน การเปลี่ยนแปลง คุณจึงสามารถดึงเกณฑ์การให้สิทธิ์เพิ่มเติมที่จัดเก็บไว้ ในฐานข้อมูล และใช้เกณฑ์เหล่านั้นในคําสั่ง @check เพื่อพิจารณาว่า การเปลี่ยนแปลงที่แนบมาได้รับอนุญาตหรือไม่ สำหรับกรณีการให้สิทธิ์นี้ @redact คำสั่งจะช่วยให้คุณควบคุมได้ว่าจะส่งผลการค้นหากลับไปยังไคลเอ็นต์ใน โปรโตคอลแบบมีสายหรือไม่ และจะละเว้นการค้นหาที่ฝังไว้ใน SDK ที่สร้างขึ้นหรือไม่ ดูข้อมูลเบื้องต้นเกี่ยวกับคำสั่งเหล่านี้พร้อมตัวอย่าง

ทำความเข้าใจคำสั่ง @auth

คุณสามารถกำหนดพารามิเตอร์ให้กับคำสั่ง @auth เพื่อให้เป็นไปตามระดับการเข้าถึงที่กำหนดไว้ล่วงหน้าหลายระดับ ซึ่งครอบคลุมสถานการณ์การเข้าถึงทั่วไปหลายอย่าง ระดับเหล่านี้มีตั้งแต่ PUBLIC (ซึ่งอนุญาตการค้นหาและการเปลี่ยนแปลงจากไคลเอ็นต์ทั้งหมดโดยไม่ต้องมีการตรวจสอบสิทธิ์ใดๆ) ไปจนถึง NO_ACCESS (ซึ่งไม่อนุญาตการค้นหาและการเปลี่ยนแปลงภายนอกสภาพแวดล้อมของเซิร์ฟเวอร์ที่มีสิทธิ์โดยใช้ Firebase Admin SDK) แต่ละระดับเหล่านี้มีความสัมพันธ์กับโฟลว์การตรวจสอบสิทธิ์ ที่ Firebase Authentication จัดเตรียมไว้

ระดับ คำจำกัดความ
PUBLIC การดำเนินการนี้สามารถดำเนินการได้โดยทุกคนที่มีหรือไม่มีการตรวจสอบสิทธิ์
PUBLIC การดำเนินการนี้สามารถดำเนินการได้โดยทุกคนที่มีหรือไม่มีการตรวจสอบสิทธิ์
USER_ANON ผู้ใช้ที่ระบุทุกคน รวมถึงผู้ใช้ที่เข้าสู่ระบบโดยไม่ระบุชื่อด้วย Firebase Authentication จะได้รับอนุญาตให้ทำการค้นหาหรือการเปลี่ยนแปลง
USER ผู้ใช้ที่เข้าสู่ระบบด้วย Firebase Authentication จะได้รับอนุญาตให้ ดำเนินการค้นหาหรือการเปลี่ยนแปลง ยกเว้นผู้ใช้ที่ลงชื่อเข้าใช้แบบไม่ระบุชื่อ
USER_EMAIL_VERIFIED ผู้ใช้ที่เข้าสู่ระบบด้วย Firebase Authentication ที่มีอีเมลที่ยืนยันแล้ว จะได้รับอนุญาตให้ทำการค้นหาหรือการเปลี่ยนแปลง
NO_ACCESS การดำเนินการนี้จะดำเนินการนอกบริบทของ Admin SDK ไม่ได้

คุณสามารถใช้ระดับการเข้าถึงที่กำหนดไว้ล่วงหน้าเหล่านี้เป็นจุดเริ่มต้นเพื่อกำหนดการตรวจสอบการให้สิทธิ์ที่ซับซ้อนและมีประสิทธิภาพในคำสั่ง @auth โดยใช้ตัวกรอง where และนิพจน์ Common Expression Language (CEL) ที่ประเมินในเซิร์ฟเวอร์

ใช้คำสั่ง @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

ในตัวอย่างต่อไปนี้ ระบบจะอ่านและเปรียบเทียบข้อมูลจากโทเค็นการให้สิทธิ์โดยใช้ นิพจน์ รูปแบบทั่วไปคือการใช้นิพจน์ เช่น where: {authorUid: {eq_expr: "auth.uid"}} เพื่อเปรียบเทียบ authorUid ที่จัดเก็บไว้กับ 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 คุณจะทดสอบ auth.uid ที่ส่งผ่าน กับ authorUid ที่จัดเก็บไว้ได้

# 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's authorization system lets you write sophisticated filters combined with preset access levels like PUBLIC as well as by using data from auth tokens.

ระบบการให้สิทธิ์ยังช่วยให้คุณใช้เฉพาะนิพจน์ได้โดยไม่ต้องมี ระดับการเข้าถึงพื้นฐาน ดังที่แสดงในตัวอย่างต่อไปนี้บางส่วน

กรองตามแอตทริบิวต์ของทรัพยากร

ในที่นี้ การให้สิทธิ์ไม่ได้อิงตามโทเค็นการตรวจสอบสิทธิ์เนื่องจากมีการตั้งค่าระดับความปลอดภัยพื้นฐานเป็น 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
  }
}
กรองตามการอ้างสิทธิ์ของผู้ใช้

ในที่นี้ สมมติว่าคุณได้ตั้งค่าการอ้างสิทธิ์ของผู้ใช้ที่กำหนดเองซึ่งส่งในโทเค็นการตรวจสอบสิทธิ์เพื่อระบุผู้ใช้ในแพ็กเกจ "Pro" สำหรับแอปของคุณ โดยมีการติดแฟล็กด้วย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
  }
}
กรองตามคำสั่ง + ขีดจำกัด

หรือคุณอาจตั้งค่า visibility ในระเบียน Post เพื่อระบุว่าระเบียนเหล่านั้นเป็นเนื้อหาที่พร้อมให้บริการสำหรับผู้ใช้ "มืออาชีพ" แต่สำหรับการแสดงตัวอย่างหรือทีเซอร์ของข้อมูล ให้จำกัดจำนวนระเบียนที่แสดงเพิ่มเติม

# 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 เพื่อค้นหาข้อมูลการให้สิทธิ์

Use Case การให้สิทธิ์ที่พบบ่อยเกี่ยวข้องกับการจัดเก็บบทบาทการให้สิทธิ์ที่กำหนดเองใน ฐานข้อมูลของคุณ เช่น ในตารางสิทธิ์พิเศษ และการใช้บทบาทเหล่านั้น เพื่อให้สิทธิ์การเปลี่ยนแปลงในการสร้าง อัปเดต หรือลบข้อมูล

การใช้การค้นหาข้อมูลการให้สิทธิ์ช่วยให้คุณค้นหาบทบาทตามรหัสผู้ใช้และ ใช้นิพจน์ CEL เพื่อตัดสินว่าการเปลี่ยนแปลงได้รับอนุญาตหรือไม่ เช่น คุณอาจต้องการเขียน UpdateMovieTitleการเปลี่ยนแปลงที่อนุญาตให้ไคลเอ็นต์ที่ได้รับอนุญาตอัปเดตชื่อภาพยนตร์

ในการอภิปรายส่วนที่เหลือนี้ ให้ถือว่าฐานข้อมูลแอปรีวิวภาพยนตร์จัดเก็บ บทบาทการให้สิทธิ์ในMoviePermissionตาราง

# MoviePermission
# Suppose a user has an authorization role with respect to records in the Movie table
type MoviePermission @table(key: ["movie", "user"]) {
  movie: Movie! # implies another field: movieId: UUID!
  user: User!
  role: String!
}

ใช้ในการเปลี่ยนแปลง

ในการใช้งานตัวอย่างต่อไปนี้ UpdateMovieTitle การเปลี่ยนแปลง มีฟิลด์ query เพื่อดึงข้อมูลจาก MoviePermission และ คำสั่งต่อไปนี้เพื่อให้มั่นใจว่าการดำเนินการมีความปลอดภัยและมีประสิทธิภาพ

  • @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
  })
}

ใช้ในการค้นหา

การค้นหาข้อมูลการให้สิทธิ์ยังมีประโยชน์ในการจำกัดการค้นหาตามบทบาท หรือข้อจำกัดอื่นๆ ด้วย

ในตัวอย่างต่อไปนี้ซึ่งใช้สคีมา MoviePermission ด้วย คําค้นหาจะตรวจสอบว่าผู้ขอมีบทบาท "ผู้ดูแลระบบ" ที่เหมาะสมในการดูผู้ใช้ ที่แก้ไขภาพยนตร์ได้หรือไม่

query GetMovieEditors($movieId: UUID!) @auth(level: PUBLIC) {
  moviePermission(key: { movieId: $movieId, userId_expr: "auth.uid" }) @redact {
    role @check(expr: "this == 'admin'", message: "You must be an admin to view all editors of a movie.")
  }
  moviePermissions(where: { movieId: { eq: $movieId }, role: { eq: "editor" } }) {
    user {
      id
      username
    }
  }
}

รูปแบบที่ไม่ควรใช้ในการให้สิทธิ์

ส่วนก่อนหน้าครอบคลุมรูปแบบที่ควรปฏิบัติตามเมื่อใช้คำสั่ง @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

# Antipattern!
# Anyone can claim an email address during sign-in
mutation CreatePost($text: String!, $visibility: String) @auth(expr: "auth.token.email.endsWith('@example.com')") {
  post_insert(data: {
    # set the author's uid to the current user uid
    authorUid_expr: "auth.uid"
    text: $text
    visibility: $visibility
  })
}

นอกจากนี้ ให้ตรวจสอบauth.token.email_verified

mutation CreatePost($text: String!, $visibility: String) @auth(expr: "auth.token.email_verified && auth.token.email.endsWith('@example.com')") {
  post_insert(data: {
    # set the author's uid to the current user uid
    authorUid_expr: "auth.uid"
    text: $text
    visibility: $visibility
  })
}

ตรวจสอบการให้สิทธิ์ด้วย Firebase CLI

ดังที่ระบุไว้ก่อนหน้านี้ ระดับการเข้าถึงที่กำหนดล่วงหน้า เช่น PUBLIC และ USER เป็นจุดเริ่มต้นสำหรับการให้สิทธิ์ที่แข็งแกร่ง และ ควรใช้ร่วมกับการตรวจสอบการให้สิทธิ์เพิ่มเติมตามตัวกรองและนิพจน์ ไม่ควรใช้โดยลำพังโดยไม่พิจารณา Use Case อย่างรอบคอบ

Data Connect ช่วยตรวจสอบกลยุทธ์การให้สิทธิ์โดยการวิเคราะห์โค้ดตัวเชื่อมต่อเมื่อคุณ ติดตั้งใช้งานในเซิร์ฟเวอร์โดยใช้ firebase deploy จาก Firebase CLI คุณใช้การตรวจสอบนี้เพื่อช่วยตรวจสอบโค้ดเบสได้

เมื่อคุณติดตั้งใช้งานตัวเชื่อมต่อ CLI จะแสดงผลการประเมินสำหรับโค้ดการดำเนินการที่มีอยู่ ที่แก้ไขแล้วและโค้ดการดำเนินการใหม่ในตัวเชื่อมต่อ

สำหรับการดำเนินการที่แก้ไขและใหม่ CLI จะแสดงคำเตือนและแจ้งให้คุณยืนยันเมื่อใช้ระดับการเข้าถึงบางอย่างในการดำเนินการใหม่ หรือเมื่อแก้ไขการดำเนินการที่มีอยู่เพื่อใช้ระดับการเข้าถึงเหล่านั้น

คำเตือนและข้อความแจ้งจะเกิดขึ้นเสมอในกรณีต่อไปนี้

  • PUBLIC

และคำเตือนและข้อความแจ้งจะปรากฏในระดับการเข้าถึงต่อไปนี้เมื่อคุณไม่ได้เพิ่มด้วยตัวกรองโดยใช้ auth.uid

  • USER
  • USER_ANON
  • USER_EMAIL_VERIFIED

ระงับคำเตือนการดำเนินการที่ไม่ปลอดภัยด้วยอาร์กิวเมนต์ @auth(insecureReason:)

ในหลายกรณี คุณจะสรุปได้ว่าการใช้สิทธิ์เข้าถึงระดับ PUBLIC และ USER* นั้นเหมาะสมอย่างยิ่ง

เมื่อตัวเชื่อมต่อมีการดำเนินการจำนวนมาก คุณอาจต้องการเอาต์พุตการตรวจสอบความปลอดภัยที่ชัดเจนและเกี่ยวข้องมากขึ้น ซึ่งละเว้นการดำเนินการที่ปกติจะทริกเกอร์คำเตือน แต่คุณทราบว่ามีการเข้าถึงในระดับที่ถูกต้อง

คุณสามารถระงับคำเตือนสำหรับการดำเนินการดังกล่าวได้ด้วย @auth(insecureReason:) เช่น

query listItem @auth(level: PUBLIC, insecureReason: "This operation is safe to expose to the public.")
  {
    items {
      id name
    }
  }

ใช้ Firebase App Check สำหรับการรับรองแอป

การตรวจสอบสิทธิ์และการให้สิทธิ์เป็นองค์ประกอบสำคัญของ Data Connect ความปลอดภัย การตรวจสอบสิทธิ์และการให้สิทธิ์ร่วมกับการรับรองแอปทำให้เกิดโซลูชันด้านความปลอดภัยที่แข็งแกร่งมาก

เมื่อใช้การรับรองผ่าน Firebase App Check อุปกรณ์ ที่เรียกใช้แอปของคุณจะใช้ผู้ให้บริการการรับรองแอปหรืออุปกรณ์ที่รับรอง ว่าการดำเนินการของ Data Connect มาจากแอปจริงของคุณ และ คำขอมาจากอุปกรณ์จริงที่ไม่มีการดัดแปลง การรับรองนี้จะ แนบไปกับทุกคำขอที่แอปของคุณส่งไปยัง Data Connect

หากต้องการดูวิธีเปิดใช้ App Check สำหรับ Data Connect และรวม SDK ไคลเอ็นต์ของ App Check ไว้ในแอป โปรดดูApp Checkภาพรวม

ระดับการตรวจสอบสิทธิ์สำหรับคำสั่ง @auth(level)

ตารางต่อไปนี้แสดงระดับการเข้าถึงมาตรฐานทั้งหมดและเทียบเท่ากับ CEL ระดับการตรวจสอบสิทธิ์จะแสดงจากระดับกว้างไปแคบ โดยแต่ละระดับจะครอบคลุม ผู้ใช้ทั้งหมดที่ตรงกับระดับต่อไปนี้

ระดับ คำจำกัดความ
PUBLIC การดำเนินการนี้สามารถดำเนินการได้โดยทุกคนที่มีหรือไม่มีการตรวจสอบสิทธิ์

ข้อควรพิจารณา: ผู้ใช้ทุกคนอ่านหรือแก้ไขข้อมูลได้ Firebase ขอแนะนําการให้สิทธิ์ระดับนี้สําหรับข้อมูลที่เรียกดูได้แบบสาธารณะ เช่น ข้อมูลผลิตภัณฑ์หรือสื่อ ดู ตัวอย่างแนวทางปฏิบัติแนะนำและทางเลือกอื่นๆ

เทียบเท่ากับ @auth(expr: "true")

@auth ตัวกรองและนิพจน์ใช้ร่วมกันไม่ได้ กับระดับการเข้าถึงนี้ การแสดงออกดังกล่าวจะล้มเหลวโดยมีข้อผิดพลาด 400 bad request
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 จึงอิงตามวิธีการ Authentication ที่มีประสิทธิภาพมากขึ้น ระดับนี้จึง ให้ความปลอดภัยเพิ่มเติมเมื่อเทียบกับ USER หรือ USER_ANON ระดับนี้จะตรวจสอบเพียงว่าผู้ใช้ได้เข้าสู่ระบบด้วย Authentication ที่มีอีเมลที่ยืนยันแล้ว และไม่ได้ทำการตรวจสอบอื่นๆ ด้วยตัวเอง เช่น ตรวจสอบว่าข้อมูลเป็นของผู้ใช้หรือไม่ ดู ตัวอย่างแนวทางปฏิบัติแนะนำและทางเลือกอื่นๆ

เทียบเท่ากับ @auth(expr: "auth.uid != nil && auth.token.email_verified")"
NO_ACCESS การดำเนินการนี้จะดำเนินการนอกบริบทของ Admin SDK ไม่ได้

เทียบเท่ากับ @auth(expr: "false")

ข้อมูลอ้างอิง CEL สำหรับ @auth(expr)

ดังที่แสดงในตัวอย่างที่อื่นในคู่มือนี้ คุณสามารถและควรใช้นิพจน์ที่กำหนดไว้ใน Common Expression Language (CEL) เพื่อควบคุมการให้สิทธิ์สำหรับ Data Connect โดยใช้คำสั่ง @auth(expr:) และ @check

ส่วนนี้ครอบคลุมไวยากรณ์ CEL ที่เกี่ยวข้องกับการสร้างนิพจน์สำหรับ คำสั่งเหล่านี้

ดูข้อมูลอ้างอิงทั้งหมดสำหรับ CEL ได้ใน ข้อกำหนด CEL

ส่งตัวแปรทดสอบในคําค้นหาและการกลายพันธุ์

@auth(expr) ไวยากรณ์ช่วยให้คุณเข้าถึงและทดสอบตัวแปรจากคําค้นหาและการเปลี่ยนแปลงได้

เช่น คุณสามารถรวมตัวแปรการดำเนินการ เช่น $status โดยใช้ vars.status

mutation Update($id: UUID!, $status: Any) @auth(expr: "has(vars.status)")

ข้อมูลที่ใช้ได้กับนิพจน์: คำขอ การตอบกลับ this

คุณใช้ข้อมูลเพื่อ

  • การประเมินด้วยนิพจน์ CEL ในคำสั่ง @auth(expr:) และ @check(expr:)
  • การกำหนดค่าโดยใช้นิพจน์เซิร์ฟเวอร์ <field>_expr

ทั้งนิพจน์ CEL @auth(expr:) และ @check(expr:) สามารถประเมินรายการต่อไปนี้ได้

  • request.operationName
  • vars (ชื่อแทนสำหรับ request.variables)
  • auth (ชื่อแทนสำหรับ request.auth)

ในการเปลี่ยนแปลง คุณสามารถเข้าถึงและกำหนดเนื้อหาของรายการต่อไปนี้ได้

  • response (เพื่อตรวจสอบผลลัพธ์บางส่วนในตรรกะแบบหลายขั้นตอน)

นอกจากนี้ นิพจน์ @check(expr:) ยังประเมินค่าต่อไปนี้ได้ด้วย

  • this (ค่าของฟิลด์ปัจจุบัน)
  • response (เพื่อตรวจสอบผลลัพธ์บางส่วนในตรรกะแบบหลายขั้นตอน)

การเชื่อมโยง request.operationName

request.operarationName binding stores the type of operation, either query or mutation.

การเชื่อมโยง vars (request.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 (request.auth)

Authentication ระบุผู้ใช้ที่ขอสิทธิ์เข้าถึงข้อมูลของคุณและให้ข้อมูลดังกล่าวเป็นข้อผูกมัดที่คุณสามารถสร้างต่อในนิพจน์ได้

ในตัวกรองและนิพจน์ คุณสามารถใช้ auth เป็นชื่อแทนของ request.auth ได้

การเชื่อมโยงการให้สิทธิ์มีข้อมูลต่อไปนี้

  • uid: รหัสผู้ใช้ที่ไม่ซ้ำกันซึ่งกำหนดให้กับผู้ใช้ที่ส่งคำขอ
  • token: แผนที่ของค่าที่รวบรวมโดย Authentication

ดูรายละเอียดเพิ่มเติมเกี่ยวกับเนื้อหาของ auth.token ได้ที่ ข้อมูลในโทเค็นการให้สิทธิ์

การเชื่อมโยง response

response Binding มีข้อมูลที่เซิร์ฟเวอร์รวบรวมเพื่อตอบสนองต่อการค้นหาหรือการเปลี่ยนแปลง ขณะที่รวบรวมข้อมูล

เมื่อการดำเนินการดำเนินไปและแต่ละขั้นตอนเสร็จสมบูรณ์แล้ว response จะมีข้อมูลการตอบกลับจากขั้นตอนที่เสร็จสมบูรณ์แล้ว

responseการเชื่อมโยงมีโครงสร้างตามรูปร่างของ การดำเนินการที่เชื่อมโยง รวมถึงฟิลด์แบบซ้อน (หลายรายการ) และคิวรีแบบฝัง (หากมี)

โปรดทราบว่าเมื่อเข้าถึงข้อมูลการตอบกลับการค้นหาที่ฝัง ฟิลด์อาจมี ข้อมูลประเภทใดก็ได้ ทั้งนี้ขึ้นอยู่กับข้อมูลที่ขอในการค้นหาที่ฝัง เมื่อคุณ เข้าถึงข้อมูลที่ฟิลด์การเปลี่ยนแปลง เช่น _insert และ _delete แสดงผล ฟิลด์ดังกล่าวอาจ มีคีย์ UUID, จำนวนการลบ, ค่า Null (ดูข้อมูลอ้างอิงการเปลี่ยนแปลง)

เช่น

  • ในการเปลี่ยนแปลงที่มีการฝังการค้นหา response การเชื่อมโยงจะมีข้อมูลการค้นหาที่ response.query.<fieldName>.<fieldName>.... ใน กรณีนี้คือ response.query.todoList และ response.query.todoList.priority
mutation CheckTodoPriority(
  $uniqueListName: String!
) {
  # This query is identified as `response.query`
  query @check(expr: "response.query.todoList.priority == 'high'", message: "This list is not for high priority items!") {
    # This field is identified as `response.query.todoList`
    todoList(where: { name: $uniqueListName }) {
      # This field is identified as `response.query.todoList.priority`
      priority
    }
  }
}
  • ในการเปลี่ยนแปลงหลายขั้นตอน เช่น มีฟิลด์ _insert หลายรายการ response การเชื่อมโยงจะมีข้อมูลบางส่วนที่ response.<fieldName>.<fieldName>.... ในกรณีนี้คือ response.todoList_insert.id
mutation CreateTodoListWithFirstItem(
  $listName: String!,
  $itemContent: String!
) @transaction {
  # Step 1
  todoList_insert(data: {
    id_expr: "uuidV4()",
    name: $listName,
  })
  # Step 2:
  todo_insert(data: {
    listId_expr: "response.todoList_insert.id" # <-- Grab the newly generated ID from the partial response so far.
    content: $itemContent,
  })
}

การเชื่อมโยง 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 หรือ [] ระบบจะไม่เข้าถึงฟิลด์และจะข้ามการประเมิน CEL สำหรับเส้นทางนั้น กล่าวคือ การประเมินจะเกิดขึ้นเมื่อ 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 AND แบบมีเงื่อนไข ซ้ายไปขวา
a || b หรือแบบมีเงื่อนไข ซ้ายไปขวา
a ? true_value : false_value นิพจน์ Ternary ซ้ายไปขวา

ข้อมูลในโทเค็นการตรวจสอบสิทธิ์

ออบเจ็กต์ auth.token อาจมีค่าต่อไปนี้

ช่อง คำอธิบาย
email อีเมลที่เชื่อมโยงกับบัญชี (หากมี)
email_verified true หากผู้ใช้ยืนยันว่าตนมีสิทธิ์เข้าถึงอีเมล email ผู้ให้บริการบางรายจะยืนยันอีเมลที่ตนเป็นเจ้าของโดยอัตโนมัติ
phone_number หมายเลขโทรศัพท์ที่เชื่อมโยงกับบัญชี (หากมี)
name ชื่อที่แสดงของผู้ใช้ หากตั้งค่าไว้
sub UID ของ 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 รหัสผู้เช่าที่เชื่อมโยงกับบัญชี (หากมี) เช่น tenant2-m6tyz

ฟิลด์เพิ่มเติมในโทเค็นรหัส JWT

นอกจากนี้ คุณยังเข้าถึงฟิลด์auth.tokenต่อไปนี้ได้ด้วย

การอ้างสิทธิ์โทเค็นที่กำหนดเอง
alg อัลกอริทึม "RS256"
iss ผู้ออก อีเมลบัญชีบริการของโปรเจ็กต์
sub เรื่อง อีเมลบัญชีบริการของโปรเจ็กต์
aud กลุ่มเป้าหมาย "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit"
iat เวลาที่ออก เวลาปัจจุบันเป็นวินาทีนับตั้งแต่ Epoch ของ UNIX
exp เวลาหมดอายุ เวลาเป็นวินาทีนับตั้งแต่ Epoch ของ UNIX ที่โทเค็นหมดอายุ โดยช้ากว่าiat ได้สูงสุด 3,600 วินาที
หมายเหตุ: การตั้งค่านี้จะควบคุมเฉพาะเวลาที่โทเค็นที่กำหนดเองหมดอายุ เท่านั้น แต่เมื่อคุณลงชื่อเข้าใช้ผู้ใช้โดยใช้ signInWithCustomToken() ผู้ใช้จะยังคงลงชื่อเข้าใช้อุปกรณ์ จนกว่าเซสชันจะใช้งานไม่ได้หรือผู้ใช้จะออกจากระบบ
<claims> (ไม่บังคับ) การอ้างสิทธิ์ที่กำหนดเองที่ไม่บังคับเพื่อรวมไว้ในโทเค็น ซึ่งเข้าถึงได้ผ่าน auth.token (หรือ request.auth.token) ใน นิพจน์ เช่น หากสร้างการอ้างสิทธิ์ที่กำหนดเอง adminClaim คุณจะเข้าถึงการอ้างสิทธิ์ดังกล่าวได้ด้วย auth.token.adminClaim

ขั้นตอนถัดไปคือ