מניעת הדפדפן מלשלוח טופס לשרת שנית. - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

מניעת הדפדפן מלשלוח טופס לשרת שנית.


gkman

Recommended Posts

שלום.

יש לי דף שמעבד טפסים שונים שנשלחים אליו (action page- הטפסים לא נמצאים באותו הדף) לאחר ביצוע הפעולה הדף מציג הודעת הצלחה ומעביר את המשתמש לדף אחר לאחר שלוש שניות.

אני רוצה לוודא שהמשתמש לא ילחץ על כפתור הרענון בשלוש שניות האלו ויגרום לדף לעבד את הנתונים מחדש.

ניסיתי להשתמש ב-

unset($_POST):

אבל זה לא עוזר כי ברענון הדפדפן שולח את הנתונים כאילו המשתמש לחץ הרגע על שליחת הטופס.

איך אפשר למנוע את זה? (אני מחפש פתרון אחר שלא כרוך בהעברה מיידית של הטופס לדף אחר.)

קישור לתוכן
שתף באתרים אחרים

הפתרון הוא להשתמש באיזשהו token שידאג לכך שהמשתמש לא יוכל לשלוח את הטופס פעמיים. כשאתה יוצר את הטופס, צור אותו עם מזהה ייחודי (עם ערך אקראי כלשהו) ושמור את הערך שלו בתוך input מסוג hidden, ובצד השרת (נניח ב-session) תשמור את המזהה של ה-token הזה. כשהמשתמש שולח את הטופס, תשווה את ה-token למה ששמור אצלך ב-session. אם הוא שלח בהצלחה, אז תמחק את ה-token ככה שאי אפשר יהיה להשתמש בו יותר.

קישור לתוכן
שתף באתרים אחרים

מצטער על ההתייחסות המאוחרת.

רק עכשיו התפניתי לזה.

אני קצצת מתקשה ליישם את ההצעה שלך.

הדרך היחידה שאני מכיר לאחסן את הsession עם המזהה הייחודי של הטופס היא בשליחה של הטופס- ואז לא פתרתי כלום כי הוא ייצור את הsession שוב ברענון. (הייתי יוצר את הsession בדף של הטופס אבל יש עליו מספר טפסים שונים אז זה לא פרקטי)

אני הבנתי שיש עוד שני דרכים להעברת נתונים חוץ מPOST וGET כמו PUT או משהו כזה... זה יעזור?

קישור לתוכן
שתף באתרים אחרים

כשאתה יוצר את הטופס, צור מזהה ייחודי (לדוגמה ע"י uniqid). שמור אותו ב-session ותוסיף אותו לטופס בתור hidden, דהיינו:

$token = uniqid("", true);
$_SESSION["token"] = $token;

ובטופס עצמו:

<input type="hidden" name="token" value="<?php echo $token; ?>" />

בדף ה-action אתה צריך להשוות את הערך של ה-token ששמור ב-session עם ה-token שקיבלת מהמשתמש, דהיינו משהו כזה:

$session_token = $_SESSION['token'];
$form_token = $_POST['token'];
unset($_SESSION['token']);

if ($session_token != $form_token) {
// error!
} else {
// good!
}

(ייתכן שיש לי טעויות בקוד, הידע שלי ב-php לא משהו)

שים לב שכיוון שאתה מאפס את מה ששמור ב-session, אי אפשר לשלוח את אותו טופס פעמיים.

נ.ב. למיטב ידיעתי uniqid לא פונקציה מספיק "בטוחה", אבל יש באינטרנט דוגמאות יותר טובות ליצירת מזהים ייחודים.

קישור לתוכן
שתף באתרים אחרים

אבל מה שכתבת לי לא פותר לי את הבעיה כי יש לי בדף שאני שולח כמה טפסים.

אז אם בsession שלי יש מזהה לטופס אחד ואני שולח את הטופס השני- יהיה לי שגיאה.

אני צריך דרך לשנות את הsession בהתאם לטופס שאני שולח.

קישור לתוכן
שתף באתרים אחרים

אז תעשה את זה לכל טופס בנפרד....

אתה גם לא חייב לייצר אחד שונה לכל טופס, מספיק שתיצור אותו פעם אחת ותכניס לכל אחד מטפסים את החלק הזה:

<input type="hidden" name="token" value="<?php echo $token; ?>" />

נ.ב.

session זה צד לקוח, לא צד שרת... session זה בסך הכל cookie..

אבל זה לא משנה, זה אמור לעבוד :)

נ.ב. 2

דפים שצריך לחכות בהם "3 שניות עד שזה עובר לדף הבא" הם אחד מהדברים הכי מעצבנים באינטרנט, כמעט כמו קאפצ'ה.

אם אין לזה מטרה אמיתית, הייתי רוצה לקוות שתנסה להימנע מזה.

קישור לתוכן
שתף באתרים אחרים

נ.ב.

session זה צד לקוח, לא צד שרת... session זה בסך הכל cookie..

תסלח לי, אבל זה לא נכון. המידע שב session נשמר בצד שרת, וניתנת גישה אליו רק מצד שרת (אי אפשר מjavascript למשל). העוגיה מכילה רק מידע מזהה שמאפשר לשרת לדעת שמדובר בגישה לאותו session.

דפים שצריך לחכות בהם "3 שניות עד שזה עובר לדף הבא" הם אחד מהדברים הכי מעצבנים באינטרנט, כמעט כמו קאפצ'ה.

אם אין לזה מטרה אמיתית, הייתי רוצה לקוות שתנסה להימנע מזה.

הסיבה שזה כל כך נפוץ במערכות פורומים למיניהם, היא שזו הדרך הכי יעילה למנוע דאבל פוסטינג בטעות כששולחים טופס דרך POST.

אם רוצים דרך 'נקיה' יותר, הפתרון הוא לעשות מה שBorn To Be Dead אמר - וכאן אני מניח שהוא התכוון לשימוש בajax במקום POST.

קישור לתוכן
שתף באתרים אחרים

תסלח לי, אבל זה לא נכון. המידע שב session נשמר בצד שרת, וניתנת גישה אליו רק מצד שרת (אי אפשר מjavascript למשל). העוגיה מכילה רק מידע מזהה שמאפשר לשרת לדעת שמדובר בגישה לאותו session.

סמנטיקה, הכוונה שלי היתה שה-session (או ה"מזהה" שלה אם תתעקש) נשמר בצד הלקוח, וזה אפשרי מבחינתו למחוק אותה אם הוא מעוניין בכך (או לזייף אותה במקרים מסויימים).

קישור לתוכן
שתף באתרים אחרים

זה לא סמנטיקה בכלל, הצורה שבה התבטאת לא קשורה למה שאתה טוען שרצית לומר.

לזייף אפשר בכל מקרה, כי בסופו של דבר המידע מגיע מצד הלקוח והוא יכול להשתמש בכל כלי אפשרי כדי לשכפל את מידע הPOST ולשלוח אותו כמה פעמים שהוא רוצה, לכן ההנחה שלי היא שמנסים למנוע שליחה חוזרת בטעות, לא בכוונה (כי את זה אי אפשר למנוע, גם אם ממש רוצים).

בנוסף לזה - ואם אני לא טועה - העוגיה משמשת רק כדי לזכור את הsession בין הפעלות של הדפדפן (שאז ממילא אין לך למה לעשות refresh), באותה הפעלה הsession יחזיק גם בלי עוגיה, ולכן לא יעזור למחוק אותה.

נזכרתי עכשיו במשהו שעשיתי בעבר:

כשאתה מקבל את המידע (ואחרי ששמרת אותו כמובן), במקום לשלוח דף חזרה תשלח בקשת redirect (למשל דרך הheader) לאותו עמוד - רק בלי מידע הPOST כמובן. במקרה של גישה פעמיים לאותה כתובת הדפדפן זוכר רק את הגישה האחרונה, כך שמידע הPOST נעלם ואין למה לעשות refresh.

קישור לתוכן
שתף באתרים אחרים

במקרה של גישה פעמיים לאותה כתובת הדפדפן זוכר רק את הגישה האחרונה, כך שמידע הPOST נעלם ואין למה לעשות refresh.

huh? ממתי?

בכל מקרה, הפתרון צריך להיות בלתי תלוי בדפדפן, והדרך לעשות זאת היא באמצעות token.

קישור לתוכן
שתף באתרים אחרים

huh? ממתי?

תנסה בעצמך: אחרי שהגיע דף מPOST (מהסוג שאם מרפרשים אותו המידע נשלח שוב), תלחץ על שורת הכתובת ותעשה אנטר (כלומר תיכנס שוב לאותו הדף). המידע של הPOST לא ישלח שוב במקרה כזה, ועכשיו גם אם תעשה refresh לא יישלח מידע POST כי אין. גם חזרה לאחור לדף הקודם תפתח לך את הדף הקודם בעל כתובת שונה, כלומר לא תוכל להגיע שוב לדף שמכיל מידע POST.

בלי קשר, לא זכרתי בדיוק, וזה לא היה מה שעשיתי. במקום, עשיתי redirect דרך הheader לכתובת שונה (עם קוד HTTP 302), ובכל זאת הכתובת הראשונה לא נשמרה בהיסטוריה (הכוונה היא שאי אפשר לחזור אליה עם כפתור back). מבחינת המשתמש זה גם שקוף לגמרי, הוא לא אמור להרגיש את הredirect בכלל - להבדיל משיטת 3 השניות.

בכל מקרה, הפתרון צריך להיות בלתי תלוי בדפדפן, והדרך לעשות זאת היא באמצעות token.

מי קבע? לי זה נראה כמו פתרון מסובך מדי ושלא לצורך. במקום זה, ajax או redirect יעבדו מצויין בכל הדפדפנים, ויהיו קלים יותר ליישום.

(לא שאני שולל את השיטה שלך, אם היא עובדת ואתה מעדיף אותה - למה לא. אבל לטעון שזו הדרך היחידה ש"נכונה" זה קצת מוגזם.)

קישור לתוכן
שתף באתרים אחרים

מי קבע? לי זה נראה כמו פתרון מסובך מדי ושלא לצורך. במקום זה, ajax או redirect יעבדו מצויין בכל הדפדפנים, ויהיו קלים יותר ליישום.

(לא שאני שולל את השיטה שלך, אם היא עובדת ואתה מעדיף אותה - למה לא. אבל לטעון שזו הדרך היחידה ש"נכונה" זה קצת מוגזם.)

קודם כל, אתה לא יכול להבטיח ב-100% איך הדפדפן יתנהג. יכול להיות שדפדפן אחד מתנהג כמו שציינת ודפדפנים אחרים לא (אני די בטוח שאין תקן לגבי איזה היסטוריה של הדף הדפדפן אמור לשמור).

חוץ מזה, זה עניין של . השימוש בtoken מונע בקשות מזוייפות (כמו שאמרתי - CSRF). לדוגמה, בלי token משתמש זדוני יכול לגרום לך לפרסם הודעות בפורום בלי ידיעתך.

קישור לתוכן
שתף באתרים אחרים

בהתחשב בעובדה שממילא תצטרך לבדוק את האתר על כל דפדפן שאתה מתכוון לתמוך בו, אתה יכול לבדוק גם את זה. לא נראה לי הגיוני להימנע מלהשתמש בשיטה או טכנולוגיה מסויימת כי אתה לא יודע אם כל הדפדפנים יתמכו בו, לפי ההיגיון הזה לא תוכל לכתוב אתרים בכלל, כי הרי תצטרך לסמוך על הדפדפן במשהו בסופו של דבר. לכן בודקים.

להשתמש בtoken שונה עבור כל טופס לא נחוץ לצרכי . בשביל זה מספיק token אחד ייחודי עבור כל משתמש (ואת זה הרבה פחות מעצבן לבצע).

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...