ทำไมไม่เปิดเผยคีย์หลัก


53

ในการศึกษาของฉันฉันได้รับแจ้งว่าเป็นความคิดที่ไม่สมบูรณ์ที่จะเปิดเผยคีย์หลักที่แท้จริง (ไม่เพียง แต่คีย์ DB แต่ผู้เข้าถึงหลักทั้งหมด) ให้กับผู้ใช้

ฉันคิดเสมอว่าเป็นปัญหาด้านความปลอดภัย (เพราะผู้โจมตีสามารถพยายามอ่านสิ่งที่ไม่ใช่ของตนเอง)

ตอนนี้ฉันต้องตรวจสอบว่าผู้ใช้ได้รับอนุญาตให้เข้าถึงหรือไม่มีเหตุผลอื่นอีกหรือไม่

นอกจากนี้เนื่องจากผู้ใช้ของฉันต้องเข้าถึงข้อมูลต่อไปฉันจะต้องมีรหัสสาธารณะสำหรับโลกภายนอกที่ใดที่หนึ่ง ตอนนี้รหัสสาธารณะมีปัญหาเช่นเดียวกับคีย์หลักใช่ไหม


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

แอปพลิเคชัน (เว็บมือถือ) ที่จัดการกิจกรรมมี UIs หลายตัวและอย่างน้อยหนึ่ง API อัตโนมัติสำหรับการสื่อสารระหว่างระบบ (eG แผนกบัญชีต้องการทราบว่าจะเรียกเก็บเงินจากลูกค้ามากน้อยเพียงใดจากสิ่งที่ทำ) แอปพลิเคชันมีลูกค้าหลายรายดังนั้นการแยกข้อมูลของพวกเขา (อย่างมีเหตุผลข้อมูลจะถูกเก็บไว้ในฐานข้อมูลเดียวกัน) เป็นสิ่งที่ต้องมีในระบบ คำขอแต่ละรายการจะถูกตรวจสอบความถูกต้องไม่ว่าจะเกิดอะไรขึ้น

กิจกรรมนั้นละเอียดมากดังนั้นมันจึงอยู่รวมกันในวัตถุคอนเทนเนอร์บางตัวให้เรียกมันว่า "งาน"

สาม usecases:

  1. ผู้ใช้ A ต้องการส่งผู้ใช้ B ไปยังงานบางอย่างดังนั้นเขาจึงส่งลิงก์ (HTTP) ให้เขาเพื่อให้กิจกรรมเสร็จสิ้นที่นั่น
  2. ผู้ใช้ B ต้องออกไปข้างนอกอาคารเพื่อเปิด Task บนอุปกรณ์มือถือ
  3. การบัญชีต้องการเรียกเก็บเงินจากลูกค้าสำหรับงาน แต่ใช้ระบบบัญชีบุคคลที่สามที่โหลดงาน / กิจกรรมโดยอัตโนมัติด้วยรหัสบางอย่างที่อ้างถึง REST - API ของแอปพลิเคชัน

แต่ละ usecases ต้องการ (หรือทำให้ง่ายขึ้นถ้า) เอเจนต์เพื่อให้มีตัวระบุที่กำหนดแอดเดรสได้สำหรับภารกิจและกิจกรรม


3
ที่เกี่ยวข้อง: กุญแจตัวแทนอาจถูกเปิดเผยต่อผู้ใช้หรือไม่? "คุณต้องพร้อมสำหรับตัวบ่งชี้ใด ๆ ที่ต้องเปิดเผยต่อผู้ใช้ / ลูกค้าที่ต้องการเปลี่ยนแปลงและเปลี่ยนข้อมูลประจำตัวของแถวในฐานข้อมูลและเผยแพร่ว่าการเปลี่ยนคีย์ต่างประเทศทั้งหมดเป็นการขอให้ทำลายข้อมูล ... "
ริ้น

@gnat ON UPDATE CASCADEถูกสร้างขึ้นสำหรับการที่ (เฉพาะ MySQL?) แต่ถ้าปัญหาคือการรักษาความปลอดภัยแล้วการตรวจสอบการเข้าถึงควรจะอยู่ในแบ็กเอนด์และไม่ไว้วางใจผู้ใช้อยู่แล้ว
Izkata

2
@Izkata ใช่ยกเว้นเมื่อคุณอ้างอิงพวกเขาในที่เก็บข้อมูลอื่น (ID ผู้ใช้ใน LDAP เป็นตัวอย่างง่ายๆ) หรือคุณจำเป็นต้องกู้คืนข้อมูลบางส่วนจากการสำรองข้อมูล ริ้นมีจุดดีที่นั่น
Angelo Fuchs

คุณสามารถดูรายละเอียดเกี่ยวกับสิ่งที่คุณหมายถึงด้วย "เปิดเผย"? ตัวอย่างจริงอาจช่วยได้ :-)
CodeCaster

"เปิดเผย" หมายถึงแสดงให้ผู้ใช้เห็น (โดยผู้ใช้ที่ผมหมายถึงมนุษย์ส่วนใหญ่ แต่คำถามที่ดูเหมือนว่าถูกต้องสำหรับเครื่องเช่นกัน)
แองเจโล Fuchs

คำตอบ:


38

นอกจากนี้เนื่องจากผู้ใช้ของฉันต้องเข้าถึงข้อมูลต่อไปฉันจะต้องมีรหัสสาธารณะสำหรับโลกภายนอกที่ใดที่หนึ่ง

เผง ใช้ HTTP แบบไร้รัฐซึ่งไม่ทราบว่าเป็นแหล่งข้อมูลใดควรขอ: เปิดเผย ID ของคำถามของคุณ218306ใน URL บางทีคุณอาจสงสัยว่าตัวระบุที่เปิดเผยอาจถูกคาดเดาได้หรือไม่?

สถานที่เดียวที่ฉันได้ยินคำตอบเชิงลบนั้นใช้เหตุผล: "แต่พวกเขาสามารถเปลี่ยน ID ใน URL!" . ดังนั้นพวกเขาจึงใช้ GUID แทนการใช้สิทธิ์ที่เหมาะสม

ฉันสามารถจินตนาการถึงสถานการณ์หนึ่งที่คุณไม่ต้องการให้ตัวระบุของคุณสามารถคาดเดาได้: การเก็บเกี่ยวทรัพยากร หากคุณมีเว็บไซต์ที่สาธารณชนโฮสต์ทรัพยากรบางอย่างที่คนอื่นอาจสนใจและคุณเป็นเจ้าภาพเช่น/images/n.jpgหรือ/videos/n.mp4ที่nเพิ่งเพิ่มจำนวนใครก็ตามที่ดูปริมาณการใช้งานไปยังและจากเว็บไซต์ของคุณสามารถเก็บเกี่ยวทรัพยากรทั้งหมดของคุณได้

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


2
URL ที่ไม่สามารถคาดเดาได้ (เช่นมีโทเค็น 128 บิตแบบเข้ารหัส) เป็นรูปแบบหนึ่งของการให้สิทธิ์ที่เหมาะสม
CodesInChaos

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

hm? เห็นได้ชัดว่ามันต้องใช้ SSL แต่ในกรณีนี้ไม่ว่าคุณจะรับรองความถูกต้องและอนุญาตก็ตาม SSL ที่ผู้โจมตีไม่สามารถเรียนรู้โทเค็น (เช่นเดียวกับพวกเขาไม่สามารถเรียนรู้คุกกี้) และยังป้องกันการโจมตีซ้ำ ข้อเสียเปรียบหลักของวิธีการนี้คือคุณไม่สามารถเพิกถอนการเข้าถึงสำหรับผู้ใช้แต่ละคนดังนั้นฉันจึงชอบที่จะใช้มันสำหรับทรัพยากรที่ไม่เปลี่ยนรูปเท่านั้น การเพิกถอนการเข้าถึงทรัพยากรที่ไม่เปลี่ยนรูปนั้นไม่มีความหมายเนื่องจากผู้โจมตีสามารถเก็บสำเนาในเครื่องได้
CodesInChaos

2
ฉันดูเหมือนจะไม่สามารถแสดงให้เห็นถึงสิ่งที่ฉันหมายถึงในวันนี้ฉันขอโทษ ฉันหมายถึงการใช้โทเค็นแบบสุ่มสำหรับทรัพยากรแบบคงที่ซึ่งตรงข้ามกับรหัสส่วนเพิ่มนั้นใช้ได้ถ้าคุณต้องการให้ทรัพยากรนั้นสามารถเข้าถึงได้แบบสาธารณะ แต่ไม่สามารถคาดเดาได้ สำหรับการใช้งานอื่น ๆ แม้ว่าฉันต้องการใช้ครั้งเดียวเพราะสิ่งที่เพิกถอน
CodeCaster

1
ไม่มีจุดของฉันอย่างแน่นอน บางทีคุณสามารถอธิบายอย่างละเอียดเกี่ยวกับสิ่งที่คุณหมายถึงด้วย "เปิดเผย" แล้ว?
CodeCaster

29

คุณไม่ควรเปิดเผยเพราะคนที่เห็นมันจะเริ่มใช้มันเป็น 'หมายเลขบัญชี' ซึ่งไม่ใช่ ตัวอย่างเช่นสำหรับบัญชีธนาคารของฉันฉันรู้ว่าหมายเลขบัญชีของฉันคืออะไร ฉันจำมันได้ฉันใช้โทรศัพท์กับบริการลูกค้าฉันใช้มันเมื่อกรอกแบบฟอร์มสำหรับธนาคารอื่น ๆ เพื่อถ่ายโอนเอกสารทางกฎหมายบริการชำระเงินอัตโนมัติ ฯลฯ ไม่ต้องการ มันจะเปลี่ยน คีย์หลัก (สำหรับบัญชีของฉัน) ในทางกลับกันฉันไม่ทราบหรือไม่เคยเห็น
ระบบที่จัดเก็บการเปลี่ยนแปลงในช่วงหลายปีที่ผ่านมาจากระบบหนึ่งไปสู่อีกระบบหนึ่งผ่านการรวมธนาคารการอัพเกรดระบบและการเปลี่ยน ฯลฯ ฯลฯ
คีย์หลักอาจเปลี่ยนไปตามการเปลี่ยนแปลงเหล่านี้บางส่วนดังนั้นหากระบบไม่เคยถูกเปิดเผย โดยผู้ใช้ปกติใด ๆ ที่ '
คีย์ที่ไม่มีความหมายทางธุรกิจมักจะเรียกว่ากุญแจตัวแทนและมักจะใช้ (แต่ไม่เสมอไป) เป็นคีย์หลัก

btw สิ่งนี้เกิดขึ้นภายในเมื่อผู้คนสร้างส่วนต่อประสานและโปรแกรมที่ใช้ในทางที่ผิดและเปิดเผยคีย์หลักและทำให้พวกเขาเป็นส่วนหนึ่งของระบบดังกล่าวแทนที่จะทำสิ่งเดียว - ระบุระเบียนฐานข้อมูลภายในโดยไม่ซ้ำกัน จริง ๆ แล้วฉันได้เรียนรู้สิ่งต่างๆข้างต้นตลอดระยะเวลา 6 ปีที่สนับสนุนระบบคลังข้อมูลในโรงพยาบาล


4
+1 แต่สิ่งที่คุณกำลังอธิบายที่นี่เป็นกุญแจแทน ไม่ใช่ทุกตารางที่มีคีย์ตัวแทนและแม้ว่าจะทำหน้าที่แทนอาจไม่ใช่คีย์ "หลัก"
nvogel

2
+1 ผมคิดว่าเลขที่บัญชีจะเป็นกุญแจแทน แต่ผมอ่านข้อมูลเกี่ยวกับมันและคุณเป็น 100% :) ที่ถูกต้อง
ไมเคิลแรนต์

2
+1 ที่เปิดเผยแก่ผู้ใช้เพิ่มความต้องการโดยนัย (เช่นคงที่)
แมตต์

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

tl; dr: เพราะอนาคต หากสิ่งภายนอกมาพึ่งพาคีย์สิ่งต่าง ๆ จะยุ่งเหยิงหากการนำไปปฏิบัติเปลี่ยนแปลงในภายหลัง ดังนั้นให้ซ่อนไว้ไม่มากก็น้อยเพื่อให้ง่ายขึ้น
Adam Tolley

27

เนื่องจากคีย์หลักเป็นรายละเอียดการใช้งาน

หากคุณย้ายฐานข้อมูลคีย์หลักของคุณอาจเปลี่ยนไปเนื่องจากคำสั่งของการแทรกการลบบันทึกเก่า ... ด้วยเหตุผลที่แตกต่างกันเล็กน้อย หากคุณโอนย้ายแพลตฟอร์มฐานข้อมูลคุณอาจไม่มีคีย์หลักที่แท้จริงอีกต่อไป การเปิดเผย PK ด้านบนชั้นการเข้าถึงข้อมูลนั้นเป็นสิ่งที่เป็นนามธรรมและมีข้อกังวลทั้งหมดที่เกี่ยวข้อง


3
เลเยอร์แอปพลิเคชันจะระบุทรัพยากรที่ต้องการดึงข้อมูลหรืออัปเดตในชั้นข้อมูลโดยไม่ต้องมีคีย์หลักได้อย่างไร
CodeCaster

2
@CodeCaster - โดยชุดของดัชนีที่ไม่ซ้ำกันหรือโดยคีย์หลักที่ไม่ใช่แบบสาธารณะที่ส่งคืนเป็นส่วนหนึ่งของวัตถุที่จัดทำโดย data access layer
Telastyn

1
@CodeCaster - มีวิธีมากมายในการสร้างโทเค็นที่ช่วยให้การโทรกลับเพื่อระบุการดำเนินการที่กำลังดำเนินการอยู่และแน่นอนว่าไม่ใช่ทั้งหมดที่พวกเขาเพียงแค่ผ่านคีย์หลักผ่าน
Telastyn

2
แต่นั่นต้องใช้ชั้นข้อมูลเพื่อทราบว่าโทเค็นใดเป็นของ (หรือแปล) ซึ่งเป็น PK สำหรับฉันแล้วดูเหมือนว่าจะมีชั้นของความซับซ้อนที่ไม่จำเป็นเพิ่มขึ้นเพียงเพื่อการซ่อน PK จุดประสงค์อะไรที่ให้บริการนอกเหนือจากความพึงพอใจของสถาปนิก? ฉันเห็นด้วยกับจุดของคุณฉันไม่พบว่ามันใช้งานได้ในการใช้งานจริงและจะขอบคุณตัวอย่างจริง
CodeCaster

1
@CodeCaster - ไม่ชั้นกลางจริง ๆ แล้วทำหน้าที่และสรุปว่ามีการเข้าถึงข้อมูลจาก UI มีสถาปนิกที่ไม่ดีมากมายในโลก แต่มีแนวทางปฏิบัติที่ดีที่สุดหลายประการของการออกแบบโปรแกรมสำหรับเหตุผล แอพบางตัวอาจเสี่ยงต่อการเกิดสิ่งที่เป็นนามธรรมและบางอย่างไม่สามารถทำได้
Telastyn

10

นี่คือคำตอบที่รวมกันของคนอื่น ๆ (aka. สิ่งที่ฉันได้เรียนรู้) หากคุณรู้สึกอยากอัปโหลดคนนี้อย่างน้อยคุณควรอัปโหลดหนึ่งในคนอื่น ๆ เช่นเดียวกับพวกเขาทำงานจริง หากคุณสนใจอ่านคำตอบอื่น ๆ แทน

คุณไม่ควรเปิดเผยคีย์หลักของฐานข้อมูล แต่ควรใช้คีย์ตัวแทนแทน

  1. หากคุณต้องการให้ผู้ใช้ของคุณสามารถจำได้ (อย่างน้อยหนึ่งบิต) หรือจดจำตัวระบุของรายการ ( Graystone28s ตอบ )
  2. หากคุณต้องการวางแผนล่วงหน้าและพิจารณาว่าคุณอาจเปลี่ยนระบบ (ฐานข้อมูลหรืออื่น ๆ ) ที่จะเปลี่ยน PK ของคุณ ( คำตอบ Telastyns )
  3. หากคุณต้องการให้แน่ใจว่าผู้ใช้ของคุณมีวิธีการที่สอดคล้องกันในการเข้าถึงข้อมูลที่จะไม่เปลี่ยนแปลงแม้ว่า บริษัท ของคุณจะเปลี่ยนความเป็นเจ้าของและข้อมูลก็จะถูกย้ายเข้าสู่ระบบที่แตกต่างกันโดยสิ้นเชิง ( Michael Durrants คำตอบ )
  4. หาก PK ของคุณสามารถคาดเดาได้ (เช่นลำดับ) ระบบของคุณอาจประสบปัญหาการเก็บเกี่ยวทรัพยากร ( คำตอบ CodeCasters ) นี้จะใช้เฉพาะถ้าระบบของคุณมีข้อมูลที่มีมูลค่าการเก็บเกี่ยวและทุกคนที่สามารถเข้าถึงได้หรืออย่างน้อยก็สามารถเข้าถึงได้

หมายเหตุ: คีย์ที่คุณสร้างขึ้นควรเป็น (kinda) คำตอบที่เข้าใจง่ายของมนุษย์ ( Sqlvogels Answer )

หากระบบของคุณไม่จำเป็นต้องมี 1 ถึง 4 ดังนั้นจึงไม่มีเหตุผลที่จะไม่ใช้ฐานข้อมูล PK เป็นตัวบ่งชี้สาธารณะของคุณ (คำตอบหลายข้อ) ความปลอดภัยไม่ใช่ปัญหาที่นี่ (คำตอบหลายข้อ)


8

เหตุผลหนึ่งที่ฉันพบในช่วงเวลาที่ฉันเห็นผู้ใช้ปลายทางขอให้ตัวระบุของพวกเขามีความหมายอะไรบางอย่าง (เช่นมีคำนำหน้าหรือตัวบ่งชี้ของปีที่ถูก incepted) การเปลี่ยน PK เป็นเรื่องยาก แต่ตัวแทนก็ง่ายกว่ามาก

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


7
คำถามคือ: "มันไม่ดีที่จะเปิดเผยคีย์หลัก?" . คำตอบของคุณ: "ผู้ใช้อาจต้องการมีตัวบ่งชี้ของตัวเอง" ฉันไม่ได้รับความสัมพันธ์ ฉันเปิดเผยInvoiceNumberซึ่งมีความหมายและสามารถเปลี่ยนแปลงได้โดยลูกค้า แต่ฉันก็เปิดเผยInvoiceIDด้วยซึ่งรหัสของฉันใช้เพื่อระบุใบแจ้งหนี้โดยเฉพาะ คุณไม่จำเป็นต้อง (และบ่อยครั้งที่ไม่ต้องการ ) เพื่อให้รหัสผู้ใช้เป็นคีย์หน่วยเก็บข้อมูล คำถามนี้เกี่ยวกับหลัง
CodeCaster

ฉันคิดว่านี่เป็นตัวอย่างที่ดีเพราะถ้าคุณย้ายไปที่แอปหลายเวอร์ชันผู้เช่าของคุณคุณสามารถใช้ไวยากรณ์เดียวกันและมีใบแจ้งหนี้หลายใบที่เหมือนกันInvoiceNumber(สำหรับผู้เช่าที่แตกต่างกัน) แต่มีคีย์หลักที่แตกต่างกัน - จุด ) กล่าวถึงในคำตอบด้วย
ฟัง

1
@CodeCaster คำถามนี้เกี่ยวกับ "ทำไมคุณไม่ต้องการให้พวกเขาเหมือนกัน"?
Angelo Fuchs

ในกรณีที่เห็นว่า Telastyns คำตอบ
CodeCaster

2

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

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

ปัญหา / ความเข้าใจผิดโดยปริยายในคำถามของคุณเกิดจากการใช้งานที่ไม่เหมาะสมของระยะหลักที่สำคัญ คีย์หลักเป็นเพียงหนึ่งในคีย์ "ตัวเลือก" หลายตัว (ตัวระบุที่เป็นไปได้หลายตัวในตารางฐานข้อมูล) คีย์หลักไม่จำเป็นต้องใช้คุณสมบัติที่แตกต่างกันโดยพื้นฐานกับคีย์อื่นใดดังนั้นการยืนยันและหลักการออกแบบที่ใช้กับคีย์หลักโดยเฉพาะและคีย์อื่น ๆ ไม่ได้สงสัยและมักจะผิดเสมอ

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


1
มันขึ้นอยู่กับอะไร? ฉันต้องการเรียนรู้ว่าอะไรคือเหตุผลที่อยู่เบื้องหลังแนวคิดทั่วไปที่จะรู้ว่าเมื่อไรที่ต้องใช้มันและไม่ใช้
Angelo Fuchs

1
สวัสดีลูกค้าโปรดให้ ID ของคุณกับฉันเพื่อฉันจะได้ช่วยคุณ แน่นอนว่ามันคือ gfds789gxb3456bgfx789fgh98076hytd6734nhg5678nghf875nhgf456 อืมแล้วสังคมของคุณล่ะ? ... id ตัวแทน
Michael Durrant

@Michael คำตอบอัพเดท นั่นเป็นกุญแจที่คุ้นเคยเรียบง่ายและมั่นคงหรือไม่?
nvogel

1

นี่คือจากความคิดเห็นคำตอบของ Greystone28 โดย CodeCaster นี่เป็นตัวอย่างของสิ่งที่คุณพูด:

ฉันเปิดเผย InvoiceNumber ซึ่งมีความหมายและสามารถเปลี่ยนแปลงได้โดยลูกค้า แต่ฉันยังเปิดเผย InvoiceID ซึ่งรหัสของฉันใช้เพื่อระบุใบแจ้งหนี้โดยไม่ซ้ำกัน คุณไม่จำเป็นต้อง (และบ่อยครั้งที่ไม่ต้องการ) ให้ผู้ใช้คีย์เป็นคีย์หน่วยเก็บข้อมูล คำถามนี้เกี่ยวกับหลัง

แอปของคุณมีวัตถุประสงค์อะไรในการเจรจากับ InvoiceID ที่ให้บริการ

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


ใบแจ้งหนี้มีตัวระบุตามธรรมชาติ (ตัวเลข) แต่มีไว้สำหรับสิ่งที่คุณเขียนเท่านั้น แล้วคนที่คุณได้รับล่ะ พวกเขามี InvoiceNumbers แต่ทับซ้อนกัน (เพราะทั้งสอง บริษัท ใช้ บริษัท เดียวกันและทั้งสองส่งใบแจ้งหนี้ถึงคุณ) ในสถานการณ์นี้ InvoiceID ของคุณไม่ซ้ำกันหมายเลขไม่ใช่และสิ่งที่ทำให้เป็นเอกลักษณ์จะเป็น Customername ซึ่งไม่ใช่ตัวบ่งชี้ที่ดีสำหรับข้อมูล (นานเกินไปการเปลี่ยนแปลงบ่อยเกินไปอาจมีอักขระที่คลุมเครือ ... )
Angelo Fuchs

@AngeloNeuschitzer - หากผู้ใช้สามารถระบุใบแจ้งหนี้โดยชื่อลูกค้าและหมายเลขผู้ใช้ไม่จำเป็นต้องใช้ InvoiceID PK แต่ฐานข้อมูลและรหัสพื้นฐานสามารถใช้งานได้ มันเป็นฟังก์ชั่นพิเศษที่ไม่เหมือนกัน
JeffO

ดูกรณีที่ 1 - 3 จากตัวอย่างของฉัน ไม่ว่ากรณีใดก็ตามชื่อลูกค้าเป็นวิธีที่มีประโยชน์ในการจัดการกับวัตถุนั้นสำหรับผู้ใช้ (ไม่ว่าจะเป็นคนหรือเครื่องจักร) InvoiceID PK คือ
Angelo Fuchs

1

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

เพื่อความสอดคล้องและความสามารถในการอ่านฉันพบว่ามันเป็นวิธีปฏิบัติที่ดีสำหรับเอนทิตีทั้งหมดในระบบเพื่อใช้ชนิดและชื่อเดียวกันที่แน่นอนสำหรับตัวระบุ โดยปกติตัวระบุนี้จะถูกเปิดเผย ( <type> getId()) ในบางคลาสฐานนามธรรม

ด้วยเหตุผลเดียวกันแต่ละบริการในระบบ (ตัวอย่างเช่นบริการใบแจ้งหนี้) ควรจัดให้มีวิธีการที่เหมือนกันสำหรับการเข้าถึงเอนทิตีด้วยตัวระบุ โดยปกติวิธีนี้ ( findById(<type> id)) จะได้รับการถ่ายทอดจากส่วนต่อประสานบริการทั่วไปหรือคลาสพื้นฐาน

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

หากระบบโยกย้ายในภายหลัง (มีขนาดใหญ่ถ้าในประสบการณ์ของฉัน) ไปยังฐานข้อมูลอื่นก็ไม่ใช่ปัญหาที่จะใช้กลยุทธ์ที่แตกต่างกัน (ไม่ได้ขึ้นอยู่กับคีย์หลัก) สำหรับการสร้างตัวระบุตราบใดที่กลยุทธ์เข้ากันได้กับต้นฉบับ


คุณช่วยอธิบายสิ่งที่คำตอบของคุณไม่ได้รับคำตอบในคนอื่น ๆ ?
Angelo Fuchs

2
ในคำตอบของฉันฉันไม่เห็นด้วยอย่างน้อยกับคะแนน 2 และ 3 ของการสรุปของคุณ ฉันไม่คิดว่าสิ่งเหล่านี้เป็นเหตุผลที่ถูกต้องหากไม่ใช้ PK เป็นตัวระบุวัตถุ
Muton

0

มีคีย์หลักอยู่ที่นั่นเหมือนกับหมายเลขอ้างอิงของ tuple (ระเบียน, แถว) ที่คุณพยายามเข้าถึงในฐานะนักพัฒนา นอกจากนี้ยังใช้ใน Referential Integrity (ข้อ จำกัด ของคีย์ต่างประเทศ) และอาจมีกรณีการใช้งานหนึ่งกรณีขึ้นไป

โดยพื้นฐานแล้วไม่มีอะไรเลวร้ายเกี่ยวกับการเปิดเผยให้ผู้ใช้หรือแฮกเกอร์ทราบ เพราะฉันไม่รู้การโจมตีที่ใช้คีย์หลักเช่น

แต่เพื่อความปลอดภัยเรามีหลักการหลายอย่าง (ซึ่งเรายอมรับและไม่อนุมัติ) และเราจำเป็นต้องปฏิบัติตาม:

  1. หลักการของสิทธิพิเศษการเช่า
  2. ความปลอดภัยผ่านความสับสน

และหลักการอื่น ๆ สิ่งที่พวกเขาพูดเป็นหลักคือ:

หากคุณไม่ต้องการเปิดเผยข้อมูลของคุณทำไมคุณถึงชอบด้วย?


ส่วนที่จับเป็นที่ที่ฉันเห็นด้วย ความปลอดภัยไม่ได้ มันอาจจะมีการรักษาความปลอดภัยที่เกี่ยวข้อง แต่มีความสำคัญภายในอิสระที่ไม่สามารถมองเห็นให้กับผู้ใช้ส่วนใหญ่จะเป็นไม่จริงเกี่ยวกับการรักษาความปลอดภัย ฉันจะเรียกว่าผลข้างเคียงที่ดี
JensG

เหตุใดคุณ: ดูตัวอย่างที่ฉันเพิ่มลงในคำถาม
Angelo Fuchs
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.