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

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

ただいまの
回答率

90.53%

  • PHP

    23558questions

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

  • JavaScript

    19922questions

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

  • Java

    15561questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Ruby

    9225questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Node.js

    2302questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

複数端末からのユーザーログインを不可にしたい場合は?

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 2,443
退会済みユーザー

退会済みユーザー

パソコンやスマホなど複数端末からの同時ログインを不可にしたいのですが、どのように同じユーザーが複数端末でログインしているか、しようとしているかを判定出来ますでしょうか?

今はユーザーログイン時に毎回トークンを発行して、そのトークンでクライアント側からAPIにリクエストを送るようにしています。

ユーザー登録時にユーザー情報とともに、そのユーザー用のトークンをdbに保存し、ユーザーがログインする時は毎回、dbに保存しておいたそのユーザー用のトークンを渡してあげれば良いでしょうか?

いや、単純にデータベースなどに各ユーザーが既にログイン状態にあるかどうかを記録しておいて、毎回、ユーザーログインがある度にそこと照らし合わせあげれば良いだけの話ですか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

トークンはユーザ登録ごとではなく、ログインごとに発行したほうがいいと思います。

  1. ログイン時にトークンを発行
  2. 発行したトークンと、ユーザIDをDBに保存(ユーザ情報のテーブルとは別)
  3. トークンはCookieに保存する。
  4. リクエストごとにCookieからトークンを取得し、DBを検索
    トークンが存在しない場合
    ログインしたユーザのIDで検索し、存在しなければトークン発行。
    存在すれば、多重ログインエラーを返却

ここで問題になるのが、トークンを格納するDBのデータ削除です。
データが残ってしまうと、別端末でのログインができなくなってしまいます。
ログイン日時などを持たせチェックしてもよいですが、
memcacheやredisなどのキャッシュDBを使うことで、期限(タイムアウト)を設定すれば
自動で削除してくれます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+2

性能と実装の容易性を別にすればご質問の内容で問題無いと思います。基本的にCSRF攻撃対策とほぼ同じです。
ただ「DBにログイン中の状態を保持する」のは(ここでいうDBが普通のRDBならば)性能問題と揮発時間の管理の難しさが伴い、けして簡単とはいえないと思います(要件次第ですが)。
アクセス数が限定的なイントラ系ならいざしらず、通常のWEBサービスであれば(インメモリDBとか特殊な仕掛けを用意しないかぎり)都度RDBへの同期書き込みはほぼNGだと思います。
このためトークンの保持はkey-value-store(redis等)をおすすめします。
また要件次第ですが揮発時間に関しては"後勝ち"方式が揮発時間を考えなくてよいので実装が楽です。
(ログインし直せばトークンが新規に発行される)
※以下スライドの21ページ「複数端末をつかったチート」がこの方式。
https://www.slideshare.net/geechs_inc/f4samuraitech-valley-20160218

あとブラウザの複数タブ使うのを前提にしてるとか、複雑な非同期通信があるとかいった場合、正規ユーザでも複数端末アクセス扱いにしてしまうバグを生みやすいので注意点が必要です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/20 22:13

    ご回答ありがとうございます!トークン上書きはシンプルで良いですね!リンク先スライドも参考になりました。ありがとうございます。


    ちなみに、「あとブラウザの複数タブ使うのを前提にしてるとか、複雑な非同期通信があるとかいった場合、正規ユーザでも複数端末アクセス扱いにしてしまうバグを生みやすいので注意点が必要です。」というのは、どういった理由からなのでしょうか?

    キャンセル

  • 2017/07/21 11:17

    例えばブラウザでtokenをhiddenで送信する場合などです。
    これだと複数タブは実質2端末アクセスのようになってしまいます。
    同じくajaxで「画面全体を書き換えない」が、「token書き換える場所が1画面に複数ある」
    場合なども作りが悪いと2回目の更新ができなくなっちゃいます。
    ※ちょっと言葉が足りなかったですがCSRFと多重ログイン同時に対応しようとした場合の話でした。
    昔cookie非対応のガラケーとかとソース併用してる場合見かけたけど今の時代不要ですよね。
    CSRFと多重ログインは別に考えた方が良い(訂正します。大変失礼しました...。)。

    キャンセル

+2

ご提示のようにDBに「ログイン中」のフラグを持っておくのが簡単だと思います。
「ログアウト」すると解除にする。
ただし、ブラウザをそのまま閉じた場合はログアウト処理を介さないので最終アクセス日時などを都度更新しておいて、一定時間更新がない場合は「ログイン中」となっていた場合でもログインを許可するなど、考慮が必要ですね。
※同端末であってもブラウザ閉じてしまった場合は一定時間経たないとログインできないってことになりますが・・

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • PHP

    23558questions

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

  • JavaScript

    19922questions

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

  • Java

    15561questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Ruby

    9225questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Node.js

    2302questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。