[Laravel 5.4] Vragenlijst maar één keer invullen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 07-10 19:27

Matis

Rubber Rocket

Topicstarter
Beste PRGers,

Op dit moment ben ik bezig met het ontwikkelen van een online vragenlijst (master thesis) voor een vriendin.
De reden om dit niet uit te besteden aan een "survey software & questionnaire tool" heeft er mee te maken dat er dynamische aspecten zitten (sliders en klikknoppen met achterliggende berekeningen) die SurveyMonkey, Google Forms etc. niet bieden. Derhalve moest er zelf iets in elkaar gezet worden.

Het is wenselijk om de vragenlijst maar één keer te kunnen invullen (per persoon).
Ik ben op zoek naar een mogelijkheid om middels Laravel 5.4 te kunnen detecteren of de gebruiker al een keer de vragenlijst heeft ingevuld.

Ik draai Laravel 5.4 middels laradock op een Ubuntu 16.04 VPS. Ik gebruik voor de opslag van de gebruikers en antwoorden een MySQL database.

De migrations-file voor de beide tabellen ziet er (momenteel) zo uit:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Schema::create('sessions', function (Blueprint $table) {
            $table->increments('id');
            $table->string('session_id')->unique();
            $table->string('ip_address', 45)->nullable();
            $table->text('user_agent')->nullable();
            $table->string('situation', 1);
            $table->timestamps();
        });

 Schema::create('answers', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('session_id')->unsigned();
            $table->string('situation');
            $table->string('sex');
            $table->string('age');
            $table->string('education');
            $table->string('education_other')->nullable();
            $table->string('salary');
            $table->string('days');
            $table->string('work_hours');
            $table->string('satisfied_salary');
            $table->string('satisfied_freetime');
            $table->string('importance_salary');
            $table->string('importance_freetime');
            $table->string('want_more');
            $table->string('greedy');
            $table->string('enough_money');
            $table->string('buy_next');
            $table->string('never_satisfied');
            $table->string('more_better');
            $table->string('salary_new');
            $table->string('days_new');
            $table->timestamps();
            $table->foreign('session_id')->references('id')->on('sessions');


Bij het starten van de vragenlijst wordt de sessie-tabel gevuld. De sessie wordt op deze manier opgebouwd:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    /* class SurveyController extends Controller */
    public function show(Request $request)
    {
        $ip_address = $request->ip();
        if($request->server('HTTP_X_FORWARDED_FOR') !== null)
        {
            $ip_address = $request->server('HTTP_X_FORWARDED_FOR');
        }
        $user_agent = $request->server('HTTP_USER_AGENT');
        $session = Session::where(['user_agent' => $user_agent, 'ip_address' => $ip_address])->first();
        if($session === null)
        {
            $count = Answer::count();
            $situation = 'a';
            if(($count % 2) == 1)
            {
                $situation = 'b';
            }
            $session_id = uniqid('', true);
            $session = new Session;
            $session->session_id = $session_id;
            $session->user_agent = $user_agent;
            $session->ip_address = $ip_address;
            $session->situation = $situation;
            $session->save();
        }
        else
        {
            $session_id = $session->session_id;
            $session->touch();
        }
        return redirect()->route('question', ['id' => $session_id]);
    }


Daarna wordt er op de vraag/antwoord pagina de volgende controle toegepast:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* class QuestionController extends Controller */
public function show(Request $request, $id = 0)
    {
        $session = Session::where('session_id', $id)->first();
        if($session === null)
        {
            return redirect()->route('welcome');
        }
        $answer = $session->answer;
        if($answer !== null)
        {
            return redirect()->route('summary');
        }
        $situation = $session->situation;
        return view('questions', compact('id', 'situation'));
    }
    public function save(StoreAnswerPost $request, $id)
    {
        $session = Session::where('session_id', $id)->first();
        if($session === null)
        {
            return redirect()->route('welcome');
        }
        $answer = $session->answer;
        if($answer !== null)
        {
            return redirect()->route('summary');
        }
        $input = $request->all();
        unset($input['_token'], $input['id']);
        $session->answer()->create($input);
        return redirect()->route('summary');
    }


Het principe werkt aardig. Alleen vrees ik dat er nu vanuit hetzelfde "huis" met dezelfde "browser / user-agent" de vragenlijst maar één keer ingevuld kan worden, ongeacht dat deze op verschillende machines draaien.
Andersom is ook het geval, dezelfde persoon kan met verschillende "browsers / user-agents" vanuit hetzelfde "huis" de vragenlijst meerdere keren invullen.

Natuurlijk is het inloggen voor deze vragenlijst een no-go. En ik ben me er ook zonder meer van bewust dat dit nooit 100% af te vangen valt voor de "kwaadwillende" gebruiker, maar ik wil in ieder geval een controle inbouwen dat dezelfde computer de vragenlijst maak één keer kan invullen.

Hebben jullie tips?

Alvast bedankt voor jullie bijdrage _O_

Matis

If money talks then I'm a mime
If time is money then I'm out of time

Beste antwoord (via Matis op 20-03-2017 14:07)


Verwijderd

Ik denk aan een cookie. Is ook niet een geweldige oplossing, maar tenzij je met accounts werkt (wat inderdaad niet echt toepasselijk is), dan kan ik me behalve browser fingerprinting niet echt wat beters bedenken.

Alle reacties


Acties:
  • Beste antwoord
  • 0 Henk 'm!

Verwijderd

Ik denk aan een cookie. Is ook niet een geweldige oplossing, maar tenzij je met accounts werkt (wat inderdaad niet echt toepasselijk is), dan kan ik me behalve browser fingerprinting niet echt wat beters bedenken.

Acties:
  • +1 Henk 'm!

  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 07:45

HaTe

haat niet

En een vragenlijst op uitnodiging is niet wenselijk? Dan moet je dus van tevoren unieke codes genereren en dan naar de personen versturen.

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 07-10 19:27

Matis

Rubber Rocket

Topicstarter
Bedankt voor jullie reacties en suggesties.
Verwijderd schreef op zaterdag 18 maart 2017 @ 09:34:
Ik denk aan een cookie. Is ook niet een geweldige oplossing, maar tenzij je met accounts werkt (wat inderdaad niet echt toepasselijk is), dan kan ik me behalve browser fingerprinting niet echt wat beters bedenken.
Misschien is een cookie toch wel de meest "veilige" manier van controle. Hoe langer ik nadenk over mijn huidige "arbitrage", hoe minder enthousiast ik word.
HaTe schreef op zaterdag 18 maart 2017 @ 09:35:
En een vragenlijst op uitnodiging is niet wenselijk? Dan moet je dus van tevoren unieke codes genereren en dan naar de personen versturen.
Het is de bedoeling een zo groot mogelijk publiek te bereiken met de vragenlijst. Natuurlijk zullen een aantal mensen direct aangeschreven worden, maar het overgrote deel zal toch via social media bij de vragenlijst uitkomen.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • +1 Henk 'm!

Verwijderd

-

[ Voor 100% gewijzigd door Verwijderd op 19-10-2019 11:42 . Reden: Leeg ivm privacy ]


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 07-10 19:27

Matis

Rubber Rocket

Topicstarter
Verwijderd schreef op zaterdag 18 maart 2017 @ 11:06:
Waarom besteed je dit niet uit aan Surveymonkey oid?
Terechte vraag. Ik heb het in mijn TS toegelicht.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • +1 Henk 'm!

  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 07:45

HaTe

haat niet

Je kan misschien een login maken zodat mensen met Google of Facebook in kunnen loggen.

Of gewoon mensen een emailadres in laten vullen. Die moet dan unieke zijn. Je kan denk ik ook best vertrouwen op het feit dat mensen niet 2x een lange vragenlijst willen invullen

[ Voor 51% gewijzigd door HaTe op 18-03-2017 13:42 ]

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


Acties:
  • 0 Henk 'm!

  • Marco1994
  • Registratie: Juli 2012
  • Laatst online: 11:11
Een (anonieme) vragenlijst invullen met een login, als ik dat zie skip ik het meteen en vul ik ze niet in. Je zou het ipadres op kunnen vragen, deze loggen en op basis daarvan checken. Het nadeel is dat je in een openbaar wifi maar een keer de enquete in kunt vullen. Een andere optie is dan een cookie idd.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

1) ofwel volledig anoniem, met een 'I'm not a robot' check van Google.
2) ofwel met op voorhand gegenereerde cookies, die deactivated worden als ze submitten
3) ofwel via log in
4) ofwel via IP (als iedereen op IPV6 was ging dit gemakkelijker :+ )

[ Voor 16% gewijzigd door Snake op 18-03-2017 16:06 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 07-10 19:27

Matis

Rubber Rocket

Topicstarter
Bedankt voor jullie feedback. Uiteindelijk toch maar voor een "ordinaire" cookie gegaan.

Zoals eerder gesteld is inloggen op een anonieme vragenlijst een no-go. Daarnaast zijn we er gemakshalve maar vanuit gegaan dat mensen de vragenlijst toch niet meer dan één keer invullen.

Mochten mensen er echt moeite voor willen doen om te "frauderen", dan kunnen we ze er altijd nog uitpikken middels de gegevens die we opslaan vanuit de HTTP-headers.

If money talks then I'm a mime
If time is money then I'm out of time

Pagina: 1