別のユーザーのセッションを更新する - ベストプラクティス? -- php フィールド と codeigniter フィールド 関連 問題

Update another user's session - best practice?












4
vote

問題

日本語

多くのWebアプリケーションのように、私のユーザーが私のサイトにログインしたときに、サイト機能にアクセスする権限を制御するいくつかのセッション変数を設定します。

ユーザーがそれらの権限に変更されるアクションを引き受けるたびに、通常の処理フローの一部としてセッション変数を更新します。

しかし、他のユーザーのアクションに基づいてユーザーのセッションを更新する必要があります。たとえば、モデレータはユーザーの権限をアップグレードします。モデレータはユーザーのセッションスペースにアクセスできないため、影響を受けるユーザーに対して通常の更新機能を実行できません。

私は他のユーザーのセッションへの更新を強制するいくつかの方法を考えましたが、それらすべてが欠点を持っています:

  • 私は彼らの検索と削除をすることができました セッションテーブルからのセッションBUT これにはフルテーブルスキャンが必要です (SessDataは '%user_id%'のようなもの)、 そしてそれは損失を引き起こす可能性があります 影響を受けるユーザーができるコンテンツ 生成に従事しています。
  • セッションの更新を強制することができました いつのように定期的に sess_time_to_updateがトリガされます。 しかし、これを保証することはありません ユーザーの前に輸送します にアクセスしようとしています 更新がそのまま機能 必要です。
  • 私は完全なシリーズを実行することができます すべてのページロードの変数更新 しかし、Aを維持するという全体のポイント セッションはそのオーバーヘッドを避けることです。
  • 私は必要性を示すフラグを設定することができます セッションの更新のために、そのシグナルのために すべてのページの実行、およびすべてのコントローラで調べる必要があります。 (私はmy_controllerとしてci_controllerを拡張できることを知っていますが、それをしたくない)
  • 私はすでにユーザーに電子メールを送信しています 変更を変更することを通知する 許可、そしてそれは十分に簡単です セッションアップデートリンクをクリックしてください (またはログアウトしてログインしてください)。 しかし彼らが保証されていない 被験者を超えて読むことさえします 行、実際にクリックしてください リンク。

だから私が欠けているものはありますか?私は存在しない魔法の弾丸を探していますか?

(CodeIgniterでこれをタグ付けし、CI固有の技術的詳細を参照してください。それは私が使用しているものです。言った、これはCI固有ではありません(またはPHP固有でさえも)問題。)

助けてくれてありがとう!

英語

As in many web applications, when my users log into my site, I set several session variables that control permissions for accessing site functionality.

Whenever a user undertakes an action that would result in a change to those permissions, I update the session variables as part of the normal processing flow.

But sometimes a user's session needs to be updated based on the actions of another user. For example, a moderator upgrades a user's permissions. The moderator does not have access to the user's session space, so the normal update functions cannot be run for the affected user.

I have considered a few ways of forcing an update to another user's session, but they all have drawbacks:

  • I could search for and delete their session from the sessions table, but this requires a full table scan (where sessdata like '%user_id%'), and it could cause the loss of content that the affected user may be engaged in generating.
  • I could force a session update periodically, such as when sess_time_to_update is triggered. But there is no guarantee that this will transpire prior to the user attempting to access the functionality for which the update is needed.
  • I could run a complete series of variable updates on every page load, but the whole point of maintaining a session is to avoid that overhead.
  • I could set a flag indicating the need for a session update, but that signal would have to be interrogated at every page execution, and in every controller. (I know that I could extend CI_Controller as MY_Controller, but I don't want to do that)
  • I'm already sending the user an email notifying them of the change in permission, and it's easy enough to make them click a session update link (or even log out and log back in). But there's no guarantee they are going to even read beyond the subject line, let alone actually click the link.

So is there anything I'm missing? Am I looking for a magic bullet that does not exist?

(Note that I've tagged this with CodeIgniter, and made reference to CI-specific technical details, because that's what I'm using. That said, this isn't a CI-specific (or even a PHP-specific) issue.)

Thanks for the help!

</div
     
 
 

回答リスト

3
 
vote
vote
ベストアンサー
 

まあ、1つのオプションは、「ACLバージョン」番号(すべてのユーザー、または各ユーザーに)設定することです。その後、セッションを初期化するとき( session_start() を呼び出すときに)保存されているバージョンがセッションのバージョンと一致するかどうかを確認します。そうでない場合は、ACLを更新してください。

もう少し異なる方法は、セッションテーブル( "status"または "dirty"などに列を追加することです。次に、セッションを強制終了する代わりに、そのステータスを 1 に更新します。その後、セッションをロードするときは、そのフラグを確認してください.1が1の場合、セッション内のキャッシュされたデータをリロードして0に設定してください。そうでない場合は...

他のユーザーのセッションを更新する限り、それはそうすることができません...セッションがPHPによって管理されている場合は、現在のセッションを強制終了して変更するものを開始する必要があります。 PHPのメカニズムはSerializeを使用していないため、それは問題を求めています...(あなたはそれをする必要があります。)

彼らのセッションを削除する限り、私は全テーブルスキャンについて心配しないでしょう。いつ常にアクセス許可を更新するユーザーがいない限り、問題ないことはありません。データ損失は大きな懸念ですので、その考えを考えています...

他の2つの選択肢まで、私はあなたが頭の上の爪を打つと思います、それで私は彼らに提供するために他に何もありません...

 

Well, one option would be to set an "ACL Version" number (either for all users, or for each user). Then when initializing the session (well, when you call session_start()) check to see if the stored version matches the session's version. If it doesn't, refresh the ACL.

Another slightly different way would be to add a column to the sessions table ("status" or "dirty", etc). Then, instead of killing the session, simply update that status to 1. Then when loading the session, check that flag to see if it's 1. If so, reload the cached data in the session and set it to 0. If not, continue on...

As far as updating another user's session, I wouldn't do that... If sessions are managed by PHP, then you'll need to kill the current session and start the one you want to modify. That's just asking for problems... (you need to do that, since PHP's mechanism does not use serialize.).

As far as deleting their session, I wouldn't worry about the full table scan. Unless you have a TON of users updating permissions all the time, it's not going to matter. The data loss is a significant concern, so that nicks that idea...

As far as the other 2 options, I think you hit the nail on the head, so I have nothing else to offer on them...

</div
 
 
       
       
2
 
vote

私は刺しゅうが刺し合うつもりですが、私のアプローチはコードイグナイターに完全に適用されません。

この問題を過去に解決した方法は、資格情報が格納されているデータベースの主キーからUSERIDを取り込むコンストラクタを使用してユーザーオブジェクトモデルを作成することです。ログイン認証情報をチェックしてからインスタンス化して、ログインが行の場合はユーザーのインスタンスをインスタンス化して返す静的ログインメソッドを書き込み、セッションを設定します。

これまでとても良い、右ですか?そのため、すべての権限、アクセスレベルなどがデータベースに保存されます。ログイン方法を持つのと同じように、オブジェクトを再設定し、すでに取得された主キーからDBから再取得するリフレッシュ方法を持つことができます。

<事前> <コード> class User{ public function __construct($uid){ //fetch from the db here $sql = 'SELECT FROM User_Table WHERE UserID = ?'; $params = array($uid); //fetch and assign using your flavor of database access, I use PDO //set all your object properties for access, as well as user_id, something like //$this->user_id = $result['UserID']; } public static function Login($uname, $pass){ $sql = 'SELECT UserID FROM User WHERE Username = ? AND Password = ?'; $params = array($uname, md5($pass)); //again I'm going to employ pseudocode here, fetch according to your preferred system if(!empty($result)){ $_SESSION['user'] = new User($result['UserID']); }else{ //login failed! return false; } } final public function _refresh(){ //refresher method. Since the controller sets all the object properties for access //reconstructing and assigning it refreshes these priveliges. $_SESSION['user'] = new User($this->user_id); } }

このモデルを使用して、私が時間依存的な権限を必要とする可能性があるセッション内のユーザーとの操作を実行しているときはいつでも、セッションですべてのユーザーオブジェクトの更新を呼び出すことができます。制限付きフォームにアクセスするためのコントローラ機能があるとしましょう。

<事前> <コード> function _topSecret(){ $_SESSION['user']->refresh(); if($_SESSION['user']->specific_permission_from_db){ //Perform the special action, get the view, whatever. }else{ //redirect to an error page } }

そのため、管理者にすでに作成されている場合は、データベース内のユーザーの権限を設定し、REFRESHメソッドが特定の時間依存関数で実行されると、そのデータが入力されます。ユーザーのセッション。だからあなたは必ずしも更新されているわけではありません。

これは私にとってかなり効率的であることが証明されていますが、再構築は最新のアクセス許可を必要とするアクションで実行する必要があるためです。繰り返しますが、それがCIとあなたの個々のアプリケーションの文脈であるかもしれないどれほど役に立つかもしれませんが、私は共有するだろうと考えました。私はあなたがすでに必要なセッションセキュリティ対策をすべて終了してセッションを始めました - CIのようなほとんどのフレームワークは彼らのネイティブ手段を通してあなたのためにこれを処理します。

 

I'm going to take a stab, though my approach is not entirely applicable to Code Igniter.

The way I've solved this problem in the past is to make a User object model with a constructor that takes the UserID from the database primary key where the credentials are stored. I'll write a static login method that checks login credentials and then instantiates and returns an instance of user if the login is correct for a row and then sets the session.

So far so good, right? So all your permissions, access levels etc are stored in the database. Just like having a login method, we can have a refresh method that reinstantiates the object, re-fetching from the db off the already obtained primary key.

class User{ public function __construct($uid){   //fetch from the db here   $sql = 'SELECT FROM User_Table WHERE UserID = ?';   $params = array($uid);   //fetch and assign using your flavor of database access, I use PDO   //set all your object properties for access, as well as user_id, something like    //$this->user_id = $result['UserID']; }  public static function Login($uname, $pass){   $sql = 'SELECT UserID FROM User WHERE Username = ? AND Password = ?';   $params = array($uname, md5($pass));   //again I'm going to employ pseudocode here, fetch according to your preferred system   if(!empty($result)){     $_SESSION['user'] = new User($result['UserID']);   }else{      //login failed!      return false;      } }  final public function _refresh(){   //refresher method.  Since the controller sets all the object properties for access   //reconstructing and assigning it refreshes these priveliges.   $_SESSION['user'] = new User($this->user_id);   }  } 

Using this model, whenever I am performing an action with the user in the session that might potentially need time-sensitive permissions, I can call refresh on the user object all ready in the session. Let's say we have a controller function to access a restricted form.

function _topSecret(){ $_SESSION['user']->refresh();  if($_SESSION['user']->specific_permission_from_db){   //Perform the special action, get the view, whatever. }else{   //redirect to an error page }  } 

So if you already have routines written for the admins, all they need to do is set the user's privileges in the database, and when the refresh method runs on the specific, time-sensitive functions, that data will be put in the session for the user. So you're not necessarily updating another user's session, you're just determining which actions are so chronologically sensitive they require the newest permissions and issuing that command to the user object in the session.

This has proven pretty efficient for me, since reconstructing need only be performed on actions that need the most up to date permissions. Again, I'm not sure how useful it may be in the context of CI and your individual application, but I figured I'd share. I'm assuming you've already done all the necessary session security measures and started the session - most frameworks like CI will handle this for you through their native means.

</div
 
 
   
   
1
 
vote

ユーザーオブジェクトの主キーを保持できるセッションテーブルに列を追加します。ログイン時に設定し、後でセッションを更新します。

編集:セッションテーブルを拡張したくない場合は、ユーザーオブジェクトIDとセッションキーのリンクがある追加のルックアップテーブルを作成します。

 

Add a column in the session table that can hold the primary key of the user object. Set it upon login and use it later to update the session.

Edit: If you don't want to extend the session table, make an additional lookup table where you have the user object id and the session key link.

</div
 
 
   
   
0
 
vote

セッションをネイティブのPHPセッションとして保存するのであれば、私はそれを一人で残す傾向があり、それらがログイン/アウトする必要があるかどうかをいくつかの方法で更新する必要があります。また、セッションデータがDBに保存されているサイトもあり、その後新しい設定を書き込むだけでは、「

 

If your're storing the session as a native php session I'd tend to leave it alone, and allow them to get some kind of notice that they need to login/out to refresh the setting. I've also had sites where the session data is stored in the db and then its much more trivial to just write the new setting in.

</div
 
 
 
 

関連する質問

2  未定義の関数anchor()内の呼び出し  ( Call to undefined function anchor in ) 
こんにちは私は<コード> PHP フレームワークの<コード> codeIgniter に登録されています。ヘルパーファイルですが、何らかの理由で私のコードが動作していないだけでなく、このエラーが発生し続けます: <事前> <コード> Fatal error: ...

0  PHPはオブジェクトの中にあるアレイのバリューを取得します  ( Php getting valuse of arrays that are inside objects ) 
このような問合せを実行しています。 <事前> <コード> int i = 0xDEADBEEF; // what can go wrong? 5 このようなオブジェクトを返します: <事前> <コード> {if cond}foo{/if} 16 これを使用...

3  PHP(CodeIgniter)ベースの求人ボードのための良い検索サービス?  ( Good search services for a php codeigniter based job board ) 
コンテンツを索引付けして検索する良いサードパーティのライセンスベースまたはオープンソース検索サービス(Yahoo Bossなど)を知っていますか? CodeIgniterにニッチ求人ボードを作成しています。私の検索がPHPにありません。 コンテンツの精製と...

2  同じフレームワークディレクトリからCodeIgniterを持つ複数のアプリケーション?  ( Multiple applications with codeigniter from same framework directory ) 
1つのCodeIgniter Frameworkディレクトリを使用して複数のアプリケーションを作成できますか? 原因別のアプリケーションに対して別々のCodeIgniterフォルダインスタンスを持つ必要があるようです。私は一箇所でいくつかのコードを調整できる...

0  コントローラセキュリティの質問におけるコードイグナイター認証コード  ( Code igniter authentication code in controller security question ) 
私の認証システムの非常にフロントエンドを処理するための主なコントローラを持っています、ログイン、ログアウト、ユーザー情報の更新などを処理します。ビュー/フォームからの投稿による呼び出しを予測します。 "delete_user"関数のようなものはどうですか?私の...

17  クライアント側またはサーバーサイドの処理?  ( Client side or server side processing ) 
だから、私は動的なWebデザインに新しい(私のサイトがPHPとほとんど静的でした)、そして私はWeb開発で最新の技術を学びようとしています(これはAjaxであるようです)、そして私は疑問に思っていましたデータをたくさん転送している場合は、サーバー上のページを構...

2  ヘルプw / codeigniter __construct()  ( Help w codeigniter construct ) 
ユーザーがログインしているかどうかを確認しています。ここでのクラスのすべての私の関数で利用できるいくつかの変数を設定したい場合は、これまでのコードです。 $ LOGGED_INまたは$ user_nameから、Viewの結果から未定義の変数になりますか?助けて...

2  多次元配列  ( Multidimensional arrays ) 
CodeIgniterでは、次のモデルがあります。 <事前> <コード> function get_item_history($id) { //from metadata_history get item_id and corresponding m...

0  CodeIgniterに関する問題。 DX_AUTHデプロイ時に機能しない  ( Problem with codeigniter dx auth not working when deployed ) 
だから現在、CodeIgniter + DataMapper overealous Edition + DX認証を使用しています。それは私達の地元のマシン、そして私達のステージングサーバーに取り組んでいます。ただし、サーバーにプッシュするとすぐに、ログインはま...

5  URLエラーを使用してコントローラに変数を渡すコードイグニタ  ( Code igniter passing variable to controller using url error ) 
このように、GETステートメントのようなURLを介して変数を渡したいコードイグナイター・プロジェクトを作成しています。 URL:/サイト/ケーキ/ 1 コントローラ機能:ケーキ($ var) しかし、変数が空白のままになっているとき、私はエラーを受け取りま...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有