質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

PHP,Javascriptで1人1回のみ投票できるような機能を実装したいのですが

gucha
gucha

総合スコア54

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

5回答

6グッド

8クリップ

13964閲覧

投稿2017/01/24 20:43

###前提・実現したいこと
ウェブページで1人1回のみ投票できるような機能を作ろうとJavascriptとPHPで構成を考えたのですが
上手く制御する方法が思いつかないので質問します。

投票する項目は動的に増加していくものを想定しています。
データベースには投票の結果のみを記録しクライアントの情報などその他の情報は、
データ量節約の為に保存しないようにしたいです。
ユーザーへの負担を減らす為にもアカウント登録制なども避けたいです。

###発生している問題・エラーメッセージ

PHPにPOSTでデータを送りPHPからデータベースへPOSTされたデータを保存する所までは作りました。
次に1人1回までという制限を作ろうと考えたのですが、POSTデータを覗かれると意図的にそのデータを作成してPHPに投げることができると気付いたので、上手く制御する方法が思いつきません。

たとえlocalstorageやcookieでPHPに渡すプログラムを制御したとしても最初に通すPOSTデータをコピーしてそのまま通せば何度でも通ってしまうと考えています。
データベースを消費して照合させる方法などは思いつくのですが容量削減の為に断念しました。

POSTの中身を覗かれないような方法があれば一番良いと考えているのですがそのような方法はありますか?
また皆様でしたら、登録制なしでデータベースには結果のみ保存という条件で1人1回の制限を実装するにはどのような方法を考えますか?

cha-ra, i-love-js, barabara👍を押しています

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答5

25

ベストアンサー

  1. 既に投票したIPアドレスからの投票を拒否する。
  2. Cookieでの制限をする。
  3. ユーザーエージェントで判断する。

以上の3点だけで通常は投票回数を制限するには事足りると思います(例外ももちろんありますが)。
あとは、悪意のある利用者に対する対策を行うと良いと思います。以下に例を挙げておきます。

  • reCAPTCHAを使う。
  • Proxy経由での投票を拒否する。
  • 海外ホストからの投票拒否。
  • CSRF対策, Refererの判定。

個人的には、IPアドレスによる制限とreCAPTCHAの導入を推奨しますが、IPアドレスの制限に関してはNATやProxyで複数IPを束ねている場合などに投票が正しくできない事態が発生するので、導入するときには注意するべきだと思います。
また、実際はこれだけ対策しても1人1回のみの投票を実現することはできません(ほぼ不可能だと思います)。しかし、不正な投票の割合は対策を怠っていた場合よりも減ると思うので、やっておくにこしたことはありません。
Webアプリケーションのセキュリティに関連する色々なことはここに載っているので、一度みてみると参考になるかもしれません。

投稿2017/01/24 21:00

編集2017/01/25 02:01
s8_chu

総合スコア14723

cha-ra, CHERRY, namimon, kei344, yambejp, Panzer_vor, sii_side, mukkun, daisy, dddd_gond, 他15名👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

退会済みユーザー

退会済みユーザー

2017/01/25 00:33

> 既に投票したIPアドレスからの投票を拒否する。 これ、一般的で善良な利用者も投稿を制限される可能性がありますよ。 たとえば、学校で隣り合った人同士が投稿しようとしたとして、片方は投稿できて片方は投稿できないといったことが発生します。
s8_chu

2017/01/25 01:31

te2jiさんの指摘されたとおり、グローバルIPアドレスを共有しているような環境ではIPアドレスによる制限を行うと正常に投票が行えなくなってしまうことを考慮していませんでした。修正させていただきました。失礼しました。
退会済みユーザー

退会済みユーザー

2017/01/25 01:49

もう一声言うと、Proxy もですね。NATだけでなく、Proxy でも IP アドレスは束ねられてしまいます。 回答にある Proxy は公開 Proxy のことだと思うので、その辺も追記されたほうが良いかと。
s8_chu

2017/01/25 02:01

なるほど。確かにそのとおりですね。指摘していただいた2点の追記をさせていただきました。

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
Panzer_vor

総合スコア1634

kei344, yambejp, motuo, takepieee, mukkun, MensJink, gucha, barabara, maisumakun👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

gucha

2017/01/25 19:34

核心をつかれ私の中での回答が見つかりました。ありがとうございました。

7

個人を特定しない以上、一人1回の投票をサーバ側で検出するのは不可能です。

IPアドレスでの制限をあげている方もいますが、むしろ善良な投稿者の投稿を制限することになるので、制限すべきではないと思います。
(会社やマンションインターネット、学校等でインターネットゲートウェイを共有している場合、同じIPアドレスで別人というケースは多々あります。また、携帯のIPアドレスも重複する可能性がかなり少ないですがあります)

方向性としては、「アカウント登録のハードルを如何に下げるか」を検討するのが正しいと思います。

投稿2017/01/25 00:29

退会済みユーザー

退会済みユーザー

総合スコア0

kei344, yambejp, Panzer_vor, mukkun, gucha, maisumakun, date👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

Panzer_vor

2017/01/25 03:29

どうでもいい話ですが、 当方宅はマンションなんで、IPではじかれると他の部屋の人が投票したら投票できなくなります( そういう意味だとIPベースの判定はローカルネットワーク内でしか現実的ではなさそうですね。
退会済みユーザー

退会済みユーザー

2017/01/25 03:54

ローカルなら個人を特定したほうが現実的かと。 ヒモ付も簡単にできると思いますし。 回答にも書きましたが、IPアドレスベースで投稿回数を1回に制限するのは、発想として間違いです。 IPアドレスが個人と1対多、多対1で結ばれる以上、個人を特定する材料としては非常にあいまいなので、善良な使用者に影響を与える可能性を考えると採用は出来ないです。 ローカルで扱うとしても、 ・一人2台以上の環境がないこと ・共有端末がないこと ・DHCPのリフレッシュに巻き込まれないこと 等、無駄な確認を多数しなければならなくなります。 VPNとか言い出したらホントメンドイです。 それよりも他のログイン情報をシングルサインオン的に使用して、個人を特定するほうが現実的です。
Panzer_vor

2017/01/25 07:46

> te2jiさん なるほど、あまり詰めて考えてなかったので参考になります。 ローカルだと認証サーバ立ててのSSOはよく聞きますが、 インターネットとなるとSSO的に考えるとOAuthを利用して認証は委譲する方が有用になるんですかね。
退会済みユーザー

退会済みユーザー

2017/01/25 07:56

最近、firebase を利用し始めたんですけど、作る側も登録する側もものすごく楽になりそうです。個人的に認証の外だしはそうとうありだと思います。

4

まぁよくあるのはEメールを送らせ、返信のEメールで投票コードのついた
urlを返信することです。
1Eメールアドレスあたり1回の制限は書けられます。
ただしそれでも捨IDを複数もっているユーザーは何度でも投票できます
ブラウザのセッションとからめてやれば少しは複数投票は防げますが
(同じブラウザからの連続投票を見極められる)
結局クッキーを消したりすればそれも効果がよわくなります

投稿2017/01/25 00:23

yambejp

総合スコア109020

kei344, Panzer_vor, gucha👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

退会済みユーザー

退会済みユーザー

2017/01/25 01:51

これ、面白いですね。やったことありませんでした。
Panzer_vor

2017/01/25 03:22

横槍ですが、 その発想には至りませんでした。 1人1回の完全な対策にはなりませんが、 選択肢としては大いにありですね。
think49

2017/01/25 06:23

面白い発想ですが、「データベースには投票の結果のみを記録しクライアントの情報などその他の情報は、 データ量節約の為に保存しないようにしたいです」に反するかもしれませんね(既出のメールアドレスをデータベースに登録しなければならないので)。 「データベースにユーザデータを保存しない」の要件が個人を特定不可能に至らしめているので、既にいわれているようにどこかで妥協点を作るしかなさそうです。

2

皆様回答ありがとうございます。
全ての回答を読みいろいろ考えたのですがやはり皆様の言われるようにデータベースに情報を蓄えないと制限は不可能だと分かりました。

今回はそれほど投票の結果に重要性がないので、ユーザーの負担とデータベースの容量の軽減を重視してまず実装はCookieで制限することにしました。
結果の重要性が高い場合は個人情報をデータベースに登録することにし、容量の節約については保存期限を定めて投票結果を破棄するなどまたその時に考えたいと思います。

投稿2017/01/25 19:20

gucha

総合スコア54

kei344👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。