###前提・実現したいこと
ウェブページで1人1回のみ投票できるような機能を作ろうとJavascriptとPHPで構成を考えたのですが
上手く制御する方法が思いつかないので質問します。
投票する項目は動的に増加していくものを想定しています。
データベースには投票の結果のみを記録しクライアントの情報などその他の情報は、
データ量節約の為に保存しないようにしたいです。
ユーザーへの負担を減らす為にもアカウント登録制なども避けたいです。
###発生している問題・エラーメッセージ
PHPにPOSTでデータを送りPHPからデータベースへPOSTされたデータを保存する所までは作りました。
次に1人1回までという制限を作ろうと考えたのですが、POSTデータを覗かれると意図的にそのデータを作成してPHPに投げることができると気付いたので、上手く制御する方法が思いつきません。
たとえlocalstorageやcookieでPHPに渡すプログラムを制御したとしても最初に通すPOSTデータをコピーしてそのまま通せば何度でも通ってしまうと考えています。
データベースを消費して照合させる方法などは思いつくのですが容量削減の為に断念しました。
POSTの中身を覗かれないような方法があれば一番良いと考えているのですがそのような方法はありますか?
また皆様でしたら、登録制なしでデータベースには結果のみ保存という条件で1人1回の制限を実装するにはどのような方法を考えますか?
以下のような質問にはグッドを送りましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
下記のような質問は推奨されていません。
- 間違っている
- 質問になっていない投稿
- スパムや攻撃的な表現を用いた投稿
適切な質問に修正を依頼しましょう。
回答5件
25
ベストアンサー
- 既に投票したIPアドレスからの投票を拒否する。
- Cookieでの制限をする。
- ユーザーエージェントで判断する。
以上の3点だけで通常は投票回数を制限するには事足りると思います(例外ももちろんありますが)。
あとは、悪意のある利用者に対する対策を行うと良いと思います。以下に例を挙げておきます。
- reCAPTCHAを使う。
- Proxy経由での投票を拒否する。
- 海外ホストからの投票拒否。
- CSRF対策, Refererの判定。
個人的には、IPアドレスによる制限とreCAPTCHAの導入を推奨しますが、IPアドレスの制限に関してはNATやProxyで複数IPを束ねている場合などに投票が正しくできない事態が発生するので、導入するときには注意するべきだと思います。
また、実際はこれだけ対策しても1人1回のみの投票を実現することはできません(ほぼ不可能だと思います)。しかし、不正な投票の割合は対策を怠っていた場合よりも減ると思うので、やっておくにこしたことはありません。
Webアプリケーションのセキュリティに関連する色々なことはここに載っているので、一度みてみると参考になるかもしれません。
投稿2017/01/24 21:00
編集2017/01/25 02:01総合スコア14723
9
s8_chuさんの回答の通りで、
ユーザアカウント、個人情報を登録しない以上は、
厳密に1人1回のみの投票の仕組みを担保するのは不可能と考えるべきです。
イントラネット利用ならともかく、インターネットの世界ではありとあらゆるネットワーク構成を考慮しなければなりません。
例えばIPアドレスベースの判定をしたとしても、
利用者端末が1つのグローバルIPに対応付けたNAPTを挟む構成であればアウトです。
(※NAPTを挟む端末全て同一IPとして払い出されるため)
考慮点が多い上に労力との費用対効果も薄いので、
0. どこかで妥協点を付ける
0. アカウントと個人情報を紐付けDBに保管し、1人1票にこだわる
上記のいずれかの戦略を選ぶこととなります。
(といっても後者でも悪意ある人がでたらめな情報入れるから1人1票は無理そうですが)
後者の場合は、個人情報の送信・DB登録が伴うため、
より厳密なセキュリティ要件の担保が必要となりますけどね。
投稿2017/01/25 00:16
編集2017/01/25 00:23総合スコア1634
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
7
個人を特定しない以上、一人1回の投票をサーバ側で検出するのは不可能です。
IPアドレスでの制限をあげている方もいますが、むしろ善良な投稿者の投稿を制限することになるので、制限すべきではないと思います。
(会社やマンションインターネット、学校等でインターネットゲートウェイを共有している場合、同じIPアドレスで別人というケースは多々あります。また、携帯のIPアドレスも重複する可能性がかなり少ないですがあります)
方向性としては、「アカウント登録のハードルを如何に下げるか」を検討するのが正しいと思います。
投稿2017/01/25 00:29

退会済みユーザー
総合スコア0
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント
2017/01/25 03:29

退会済みユーザー
2017/01/25 03:54
2017/01/25 07:46

退会済みユーザー
2017/01/25 07:56
4
まぁよくあるのはEメールを送らせ、返信のEメールで投票コードのついた
urlを返信することです。
1Eメールアドレスあたり1回の制限は書けられます。
ただしそれでも捨IDを複数もっているユーザーは何度でも投票できます
ブラウザのセッションとからめてやれば少しは複数投票は防げますが
(同じブラウザからの連続投票を見極められる)
結局クッキーを消したりすればそれも効果がよわくなります
投稿2017/01/25 00:23
総合スコア109020
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
回答へのコメント

退会済みユーザー
2017/01/25 01:51
2017/01/25 03:22
2017/01/25 06:23
2
皆様回答ありがとうございます。
全ての回答を読みいろいろ考えたのですがやはり皆様の言われるようにデータベースに情報を蓄えないと制限は不可能だと分かりました。
今回はそれほど投票の結果に重要性がないので、ユーザーの負担とデータベースの容量の軽減を重視してまず実装はCookieで制限することにしました。
結果の重要性が高い場合は個人情報をデータベースに登録することにし、容量の節約については保存期限を定めて投票結果を破棄するなどまたその時に考えたいと思います。
投稿2017/01/25 19:20
総合スコア54
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
このような回答には修正を依頼しましょう。
関連した質問
Q&A
解決済
最速で配列からデータを取り出し、正規表現で検索したい。
回答3
クリップ1
更新
2023/01/31
意見交換
クローズ
JSの変数名の先頭に$マークをつける理由
回答12
クリップ2
更新
2023/02/01
Q&A
解決済
JDBCとJSPを用いた住所検索システムを作成したい
回答2
クリップ0
更新
2023/01/31
Q&A
解決済
jsとgasによるdoPostとfetch間によるhtmlファイルの受け渡しについて
回答1
クリップ2
更新
2023/01/30
Q&A
解決済
ajax使用時にPHPでPDOを行うと正常に返ってこない
回答2
クリップ0
更新
2023/01/30
Q&A
解決済
PHP プレースホルダに対して配列の値をバンドしたい
回答1
クリップ1
更新
2023/01/28
Q&A
受付中
JavaScriptでエラーをキャッチできる場合とできない場合の違い
回答4
クリップ3
更新
2023/01/31
Q&A
解決済
JavaScriptの変数に入れた値を、同一ファイル内のPHPの変数で受け取りたいです
回答1
クリップ0
更新
2023/01/31
同じタグがついた質問を見る
HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。
SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。
PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。
JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。
良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
退会済みユーザー
2017/01/25 00:33
2017/01/25 01:31
退会済みユーザー
2017/01/25 01:49
2017/01/25 02:01