Προς το περιεχόμενο

PHP / MySQL / JavaScript: προσθήκη περιορισμένου χρόνου σε seconds να δώσει κάποιος απάντηση σε μια ερώτηση Quiz


philos
Μετάβαση στην απάντηση Απαντήθηκε από Predatorkill,

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Καλησπέρα!

Φτιάχνω ένα quiz σύστημα σε μια πλατφόρμα βασισμένη σε PHP/MySQL.
Η πλατφόρμα φορτώνει ήδη και το jQuery.

Τι ακριβώς κάνω; Φορτώνω μέσω ajax call, μία ερώτηση κάθε φορά στον browser με τα choices της.
Το κύριο χαρακτηριστικό είναι ότι για κάθε ερώτηση υπάρχει συγκεκριμένο περιθώριο κάποιος να δώσει την απάντηση, πχ 30 seconds.
Μετά τα 30 seconds τρέχει η loadNextQuestion() javascript function που κάνει ajax call για να φορτωθεί η επόμενη ερώτηση.

Μπορεί κάποιος να κάνει submit την απάντηση πριν τα 30 seconds φυσικά.

Πως να το στήσω να "λειτουργεί" ξέρω, όμως το θέμα είναι ότι δεν ξέρω πως να κάνω κάποιον με ελάχιστες γνώσεις να ΜΗΝ μπορεί να χακάρει το όριο των 30 κτλ seconds ανά ερώτηση.

Υποθέτω ότι κάτι πρέπει να γίνει σε επίπεδο PHP / MySQL.

Θα μπορούσα πχ όταν ο browser κάνει request την ερώτηση στο PHP script, να σώζω το timestamp + question_id στη MySQL και να το συγκρίνω όταν ο χρήστης δίνει την απάντηση / τρέχει η loadNextQuestion().

Πως σας φαίνεται σαν ιδέα;
Σκέφτομαι μήπως υπάρχουν αποκλίσεις σε seconds, πχ να κάνει το request ο browser στον server, ο server να δώσει απάντηση κτλ. Τι λέτε;

Τα εργαλεία μας είναι τα παραπάνω (PHP/MySQL/JavaScript/jQuery), pls μην με προωθήσετε σε τίποτα τρελές τεχνολογίες που θα πρέπει να διαβάσω ολόκληρο documentation μόνο για ένα χαρακτηριστικό σαν το παραπάνω, εκτός αν πραγματικά δε βγαίνει αλλιώς. :P

Επεξ/σία από philos
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 32
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ. (επεξεργασμένο)

Καντο αναποδα, ο σερβερ να στελνει timestamp στον client οταν εμφανιζεται η ερωτηση και οταν γινει submit η απαντηση κανε τα checks σου παλι στον σερβερ (με unix timestamp οχι με iso)

Επεξ/σία από Predatorkill
  • Thanks 3
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
3 λεπτά πριν, Predatorkill είπε

Καντο αναποδα, ο σερβερ να στελνει timestamp στον client οταν εμφανιζεται η ερωτηση και οταν γινει submit η ερωτηση κανε τα checks σου στον σερβερ (με unix timestamp οχι με iso)

Μπορείς να το κάνεις λίγο πιο νιανιά για τον έλεγχο που θα κάνω εφόσον θα είναι ανάποδος; :P

Ασφαλώς μπορώ να το υλοποιήσω, απλά θέλω να έχω στο μυαλό μου λεκτικά τη λογική.

Ναι πάντα unix timestamp χρησιμοποιώ.

ΥΓ: Το αναλογίζομαι ήδη πως μπορώ να το κάνω..

Επεξ/σία από philos
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Λύση
Δημοσ. (επεξεργασμένο)
1 ώρα πριν, philos είπε

Μπορείς να το κάνεις λίγο πιο νιανιά για τον έλεγχο που θα κάνω εφόσον θα είναι ανάποδος; :P

Ασφαλώς μπορώ να το υλοποιήσω, απλά θέλω να έχω στο μυαλό μου λεκτικά τη λογική.

Ναι πάντα unix timestamp χρησιμοποιώ.

ΥΓ: Το αναλογίζομαι ήδη πως μπορώ να το κάνω..

Οταν καλεις την ερωτηση απο τον client στειλε πισω και την ωρα που εγινε η κληση μαζι με την ερωτηση.

Οταν ο χρηστης δωσει απαντηση τοτε στειλε και την ωρα που υποβληθηκε. Αν η ωρα εχει διαφορα <= 30 δευτερολεπτα τοτε εισαι οκ, αλλιως παιζει μαϊμουδια στον client.

δωσε εναν «αερα» του ενος δευτερολεπτου για το latency,.

Λαβε στα υποψην και το γεγονος οτι καποιος μπορει να μην διαβασει καν την ερωτηση και να απαντησει αμεσως σε 1 δευτερολεπτο (edge case αλλα ποτε δε ξερεις). 

Επεξ/σία από Predatorkill
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

17 λεπτά πριν, Predatorkill είπε

Οταν ο χρηστης δωσει απαντηση τοτε στειλε και την ωρα που υποβληθηκε. Αν η ωρα εχει διαφορα <= 30 δευτερολεπτα τοτε εισαι οκ, αλλιως παιζει μαϊμουδια στον client.

χμμ άλλη μια ερώτηση σε αυτό (αύριο θα ασχοληθώ με την υλοποίηση και θα δω τι προκύπτει) : όταν στέλνω την ώρα που υποβλήθηκε η απάντηση, υποθέτω ότι είναι η ώρα της javascript, σωστά;

Αν ο server έχει διαφορετική ώρα σε seconds δεν παίζει bug;

Καλά εγώ σε localhost δουλεύω αυτή τη στιγμή, άρα δε θα το αντιληφθώ, απλά ρωτάω στη πράξη.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

8 hours ago, Predatorkill said:

Οταν καλεις την ερωτηση απο τον client στειλε πισω και την ωρα που εγινε η κληση μαζι με την ερωτηση.

Οταν ο χρηστης δωσει απαντηση τοτε στειλε και την ωρα που υποβληθηκε. Αν η ωρα εχει διαφορα <= 30 δευτερολεπτα τοτε εισαι οκ, αλλιως παιζει μαϊμουδια στον client.

δωσε εναν «αερα» του ενος δευτερολεπτου για το latency,.

Λαβε στα υποψην και το γεγονος οτι καποιος μπορει να μην διαβασει καν την ερωτηση και να απαντησει αμεσως σε 1 δευτερολεπτο (edge case αλλα ποτε δε ξερεις). 

Και έτσι όμως θα μπορέσει ο client να πειράξει την ώρα που έστειλε ο server σωστά;

Αν θέλεις να είσαι 100% σίγουρος πως δεν την έχει πειράξει ο client θα πρέπει να την κρυπτογραφήσεις με κάποιο κλειδί που έχει μόνο ο server και να στείλεις το hash στον client για να μην μπορεί να γίνει tampered.
Ο client θα στείλει πίσω την απάντηση μαζί με το hash και στον server θα κάνεις decrypt την ώρα και θα ελέγχεις αν είναι πάνω από 30 δευτερόλεπτα από την current ώρα του server.

Με αυτό τον τρόπο γλυτώνεις και θέματα timezone.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κάθε submit επικοινωνεί με τον server σωστά; Άρα αφού θα έχει αρχικό timestamp από τον server παίρνεις και δεύτερο timestamp από τον server κατά το submit και κάνεις τον αντίστοιχο έλεγχο για το αν διαφοροποιείται κατά 30 (+1 ή κάτι τέτοιο όπως είπε ο @Predatorkill) και ουσιαστικά λύνεται το πρόβλημα που αναφέρει ο @Xvipes.

Επίσης γιατί να έχει πρόσβαση ο client στο timestamp. Η διαχείριση ας γίνεται μέσω κάποιου php αρχείου και ajax call. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

1 hour ago, rafinos said:

Κάθε submit επικοινωνεί με τον server σωστά; Άρα αφού θα έχει αρχικό timestamp από τον server παίρνεις και δεύτερο timestamp από τον server κατά το submit και κάνεις τον αντίστοιχο έλεγχο για το αν διαφοροποιείται κατά 30 (+1 ή κάτι τέτοιο όπως είπε ο @Predatorkill) και ουσιαστικά λύνεται το πρόβλημα που αναφέρει ο @Xvipes.

Επίσης γιατί να έχει πρόσβαση ο client στο timestamp. Η διαχείριση ας γίνεται μέσω κάποιου php αρχείου και ajax call. 

Έτσι όμως θα πρέπει ο server να κρατάει κάπου το state για κάθε χρήστη και κάθε ερώτηση.

Εκτός αν κτλβα κάτι λάθος. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

47 λεπτά πριν, Xvipes είπε

Έτσι όμως θα πρέπει ο server να κρατάει κάπου το state για κάθε χρήστη και κάθε ερώτηση.

Εκτός αν κτλβα κάτι λάθος. 

Όχι καλά κατάλαβες. Στο σέρβερ δεν μπορεί να γίνει διαφορετικά.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Ναι, όταν φορτώνεις την επόμενη ερώτηση, ταυτόχρονα κάνεις submit και την απάντηση της τρέχουσας ερώτησης (ακόμα και αν ο χρήστης δεν επέλεξε κάποιο choice / η ερώτηση θα μαρκαριστεί ως αναπάντητη και δε θα μετρήσει στο pass score).

Όπως σας είπα υπάρχει δυνατότητα MySQL στο server και να σώζω ο,τιδήποτε (question_id / unix timestamps κτλ).

Νομίζω αυτό που περιγράφεις @rafinos είναι αυτό που περιγράφω στο αρχικό μήνυμα;

Όπως έγραψα με ανησυχούν οι καθυστερήσεις μεταξύ της επικοινωνίας server - client που μπορούν να αγγίξουν ολόκληρα seconds. Η ιδέα του @Predatorkill να κάνω submit την ακριβή ώρα που ο χρήστης έδωσε την απάντηση / τρέξει η loadNextQuestion() είναι καλή, αλλά μιλάμε για javascript ώρα του υπολογιστή που τρέχει τον browser οπότε δεν ξέρω αν ευσταθεί.

Αυτό με το encrypt και decrypt του hash δεν το κατάλαβα. Ξέρω μεν να κάνω md5() hashes και να το επιστρέψω στον client αλλά δε ξέρω μετά πως να το κάνω decrypt. Ίσως κάποιο PHP παράδειγμα θα ήταν βοηθητικό.

Επεξ/σία από philos
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Αν δεν σε πειράζει να κρατάς εφήμερα states σε sql τότε μια χαρά κάνεις αυτό που λέει ο @rafinos

Αν θες να πας με encrypt/decrypt τότε ένα ξεκάθαρο παράδειγμα έχει εδώ https://www.javatpoint.com/how-to-encrypt-or-decrypt-a-string-in-php#:~:text=In the PHP programming language,both methods of PHP language.

Ο server θα δημιουργεί το timestamp και θα το κρυπτογραφεί και θα το στέλνει μαζί με την ερώτηση. O client θα στέλνει πίσω την απάντηση μαζί το κρυπτογραφημένο timestamp και ο server θα διαβάζει και θα συγκρίνει το timestamp. 

Με αυτό τον τρόπο δε θα έχεις και ορφανές εγγραφές στην βάση, αν κάποιος δεν απαντήσει, που με κάποιο τρόπο θα πρέπει να καθαρίζεις τακτικά. 

 

Επεξ/σία από Xvipes
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Ας πούμε κάτι τέτοιο δλδ;

1. Κρυπτογραφώ το string 9-1696780758-blahblah, ας πούμε το hash που προκύπτει είναι το abc123.

9 = το question_id

μετά το time() unix timestamp (NOW)

blahblah = ένα salt

2. Το στέλνω (το abc123) στον browser μαζί με την ερώτηση, το question_id και τα choices.

3. Ο χρήστης απαντάει και γίνεται submit η απάντηση μαζί με το abc123 και στο question_id πίσω στον server.

4. Κάνω decrypt το abc123. Προκύπτει 9-1696780758-blahblah το οποίο περνάω στη $hash μεταβλητή.

5. Κάνω $arr = explode('-', $hash).

6. Τσεκάρω αν $arr[0] == το question_id της απάντησης που έδωσε ο χρήστης.

7. Τσεκάρω αν time() - $arr[1] <= 30 seconds

+/- 1 second για τις καθυστερήσεις του server.

 

Κάτι τέτοιο;

Επεξ/σία από philos
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Τώρα που το ξανασκέφτομαι αν είναι και τα δύο timestamps από τον server τότε θα υπάρχει ζήτημα σε περίπτωση που το response με τον server γίνει καθυστερημένα στο submit. Αλλά και στο φόρτωμα της ερώτησης παίζει ρόλο πόσο θα καθυστερήσει. Οπότε νομίζω ότι η καθυστέρηση επικοινωνίας με τον server είναι πολύ σημαντική παράμετρος ανάλογα την υλοποίηση. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
1 hour ago, philos said:

Ας πούμε κάτι τέτοιο δλδ;

1. Κρυπτογραφώ το string 9-1696780758-blahblah, ας πούμε το hash που προκύπτει είναι το abc123.

9 = το question_id

μετά το time() unix timestamp (NOW)

blahblah = ένα salt

2. Το στέλνω (το abc123) στον browser μαζί με την ερώτηση, το question_id και τα choices.

3. Ο χρήστης απαντάει και γίνεται submit η απάντηση μαζί με το abc123 και στο question_id πίσω στον server.

4. Κάνω decrypt το abc123. Προκύπτει 9-1696780758-blahblah το οποίο περνάω στη $hash μεταβλητή.

5. Κάνω $arr = explode('-', $hash).

6. Τσεκάρω αν $arr[0] == το question_id της απάντησης που έδωσε ο χρήστης.

7. Τσεκάρω αν time() - $arr[1] <= 30 seconds

+/- 1 second για τις καθυστερήσεις του server.

 

Κάτι τέτοιο;

Yip μια χαρά το σκέφτηκες!

Επεξ/σία από Xvipes
  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)
27 λεπτά πριν, rafinos είπε

Τώρα που το ξανασκέφτομαι αν είναι και τα δύο timestamps από τον server τότε θα υπάρχει ζήτημα σε περίπτωση που το response με τον server γίνει καθυστερημένα στο submit. Αλλά και στο φόρτωμα της ερώτησης παίζει ρόλο πόσο θα καθυστερήσει. Οπότε νομίζω ότι η καθυστέρηση επικοινωνίας με τον server είναι πολύ σημαντική παράμετρος ανάλογα την υλοποίηση. 

Ναι το σκέφτηκα κι εγώ αυτό και με προβληματίζει, το αναφέρω και στο πρώτο μήνυμα.

Γι' αυτό λέω να δώσω άφθονο περιθώριο του στυλ +/- 15 seconds. Άλλωστε το πρόβλημα θα ήταν μη χάκαρε κάποιος το σύστημα κι έλυνε με το πάσο του το quiz.

Από την άλλη υπάρχει και η λύση να κάνω submit στον server την unix time που έγινε το submit από τον χρήστη, όμως εδώ όπως σας είπα με προβληματίζει ότι άλλη ώρα θα έχει σε unix time ο server και άλλη ώρα η javascript που θα ακολουθεί την ώρα του browser / συστήματος. Είναι πάρα πολύ πιθανό να έχει διαφορά σε seconds.

Επίσης δε ξέρω πως να κάνω κρυπτογράφηση σε επίπεδο javascript, γιατί ο άλλος θα μπορούσε να τροποποιούσε την ώρα του submit που περνάει στο submit ajax call.

Αν έχετε να προτείνετε κάποια επιπρόσθετη λύση για να αποφύγω το +/- 15 seconds / γενικά το πρόβλημα το response time / γενικά αυτό το πρόβλημα, ας μας πει. :)

Επεξ/σία από philos
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...