0

ユーザーがサインインしているかどうか (つまり、メニュー項目が表示されているかどうか) に基づいてトリガーされる多くのフロントエンド関数がありますが、ユーザーがサインインしたときにそれらがリダイレクトされたり、ページが変更されたりしない限り、それらをトリガーするのに問題があります。リフレッシュされます。

$logged_inユーザーがログインしたときに設定される値を変更するにはどうすればよいですか? $_SESSION['SESS_USER_ID'] = $member['user_id'];サインイン後の設定も含め、機能はすべて正常に動作しています。

Index.php (このコードの多くはサイト全体でも使用されています)

ドキュメントの冒頭:

<?php    
require_once('auth.php'); // This file starts session, and checks if(!isset($_SESSION['SESS_USER_ID']) || (trim($_SESSION['SESS_USER_ID']) == ''))  
require_once('config.php'); // Connects to database connection   
$user_id = $_SESSION['SESS_USER_ID'];       
$logged_in = (isset($_SESSION['SESS_USER_ID']));
?>

次に、関連する関数が $logged_in によってトリガーされ、次の基本的な形式に従います。

<?php if ($logged_in) : ?>
// Some HTML or Script
<?php else : ?>
// Some HTML or Script
<?php endif; ?>

サインインフォームと機能

AJAX の一部が無関係である場合は、申し訳ありません。

<form id="loginForm" name="loginForm" action="login-exec_pdo.php"  method="post">  
<label for="user_name">Username </label><input type="text" name="user_name" required />
<label for="password">Password </label><input type="text" name="password" required />
<div id="return_result"></div><div id="messageBox5">Please complete the highlighted    fields</div>                  
<input type="submit" id="login" value="Sign in" />
</form>

<script type="text/javascript">
$(function () { $('#loginForm').validate({          
rules: {user_name: {required: true, minlength: 2,}, password: {required: true, minlength: 6,},}, messages: {user_name: "", password: "",},      
errorLabelContainer: "#messageBox5", 
submitHandler: function (form){
  $.ajax({
    type: 'POST',
    url: 'login-exec_pdo.php',
    data: $("#loginForm").serialize(),
    success: function(data) {   
      if(data == "true") {
        $("#loginForm").fadeOut("fast");
      }
      else {
        writeToTarget('return_result', 'Incorrect Username or Password');
}  }  });  }   });  });  
</script>

login-exec.php ファイル

<?php
session_start();
require_once('config/config_pdo.php'); // Includes db connection, salt, & PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION
$password = $_POST['password'];  
$hashedPassword = sha1($salt . $password); 

try {  
   $stmt_user = $conn->prepare("SELECT * FROM customer_info WHERE user_name = :user_name and password = :hashedPassword");  
   $stmt_user->bindValue(':user_name', $_POST['user_name'], PDO::PARAM_STR); 
   $stmt_user->bindValue(':hashedPassword', $hashedPassword);     
   $stmt_user->execute();                 
   session_regenerate_id();                  
   $member = $stmt_user->fetch();                 
   if($member) {                  
      $_SESSION['SESS_USER_ID'] = $member['user_id'];  
      $_SESSION['SESS_USER_NAME'] = $member['user_name'];             
      session_write_close(); 
      echo "true";                 
      exit();
   }else {
      echo "false";
      exit();
   }                    
}catch(PDOException $e) {
  echo $e->getMessage();
}                 
?>

また、javascript と php の両方を使用して、サインイン関数内の成功関数 (上記の場所) に設定しようとしましたが、設定しなかったか、ログイン関数が正しく完了しませんでした。私が試したことのいくつかは次のとおりです if ($logged_in) : $logged_in = (isset($_SESSION['SESS_USER_ID'])); $logged_in = "true";$logged_in = 1;

4

2 に答える 2

1

はじめに

少し頭が痛いので、まずあなたの明らかな間違いを見せてください

間違い #1
JavaScript を直接使用して PHP 変数を設定することはできません。これは、JSON/XML で交換することによってのみ可能です。

submitHandler: function (form){

    $.ajax({type: 'POST', url: 'login-exec_pdo.php', data: $("#loginForm").serialize() ...

    success: function(data) {

        if (data == "true") { 

            $("#loginForm").fadeOut("fast");

            // THIS IS WHERE I'VE TRIED TO SET $logged_in


            // 1. You can't set $logged_in to true right from this point
            // You should send JSON or XML back to PHP invoking a new nested ajax call
            // and then parse that stuff in PHP and then send the parsed stuff back to JavaScript.
            // However, this is some kind of bad approach, because A) you invoke a nested ajax call
            // B) you make it even worse to debug and maintain C) 

            // 2. You serialized the form but never used it

        ....

間違いその2

責任の混合とコードの重複。正確には:データベースハンドラー(db構成を含む)とユーザーの責任を混在させる(以下の説明を参照)

$stmt_user = $conn->prepare("SELECT * FROM customer_info WHERE user_name = :user_name and password = :hashedPassword");  <-- LIMIT 1 keyword should be appended
$stmt_user->bindValue(':user_name', $_POST['user_name'], PDO::PARAM_STR); 
$stmt_user->bindValue(':hashedPassword', $hashedPassword); //<-- btw, you've missed PDO::PARAM_STR here
$stmt_user->execute();
...                
session_regenerate_id();  //<-- This should be done after successful authorization, not before                  
$member = $stmt_user->fetch();                 
if($member) {    //if you have error_reporting(E_ALL) you'll see a E_NOTICE 
   $_SESSION['SESS_USER_ID'] = $member['user_id'];
   session_write_close(); 
   echo "true"; //<-- Single quotes should be used instead of double ones.
   exit();
}else {
   echo "false";
   exit();
}  

じゃあ良いよ。それがログインページだとします。しかし、実際のシナリオでは、ユーザーのプロフィール ページでもデータベースが使用されます。コードによると、同じデータベース ハンドラを 2 回以上実装する必要があります... (以下のコメントを参照)

間違い #3
エラー追跡がまったくなく、クライアント側の検証に依存している。

基本的に、クライアント側の検証は決して信頼すべきではありません。ブラウザーで JavaScript を無効にすることは誰にでもできるからです。そして、「無効な」データを PHP スクリプトに簡単に送信できます。常にサーバー側の検証を行ってください! ただし、クライアント側の検証をまったく使用してはならないという意味ではありません。
代わりに、JS が有効になっていない/サポートされていないブラウザーから送信された場合に対処する必要があります。自分で試すことができます。ブラウザで JavaScript を無効にしてから、サイトにアクセスしてください...

間違い #4
コードの重複は言うまでもなく、コード自体が適切に構造化されていません。これは、これであってはならない方法です。ここでは、JavaScript コードと PHP コードの両方について説明しています...


さて、これをどのように修正する必要がありますか

上記のアドバイスに従うかどうかはわかりませんが (時間がない場合や意志がない場合に備えて)、最初の質問に最初に答えさせてください。

$logged_inユーザーがログインしたときに設定される値を変更するにはどうすればよいですか?

要するに: これは PHP 変数です! したがって、PHPで設定する必要があります。$logged_inユーザーがログインしたときにTRUEに設定したとしても、どこかを見逃していsession_start()ます。ただし、この変数は絶対に使用しないでください。is_user_logged()代わりに、何か問題が発生した場合に信頼性が高く、「キャッチ可能」であるため、関数を定義します。よし、次は

生活を楽にするために、これらの関数を定義するだけです:

/**
 * Checks whether user logged in
 * 
 * @return boolean TRUE if user is logged in
 *                 FALSE if not
 */
function is_user_logged(){
   //if session isn't started yet
   if ( session_id() == ''){
      // do start it now
      session_start();
   }

   if ( isset($_SESSION['SESS_USER_ID']) ){
      return true; 
   }

   return false;
}

/**
 * Retrieves an ID of the logged user if he's really logged
 * NULL otherwise
 * 
 * @return string|null
 */
function get_logged_user_id(){

   if ( is_user_logged() === TRUE ){
      return $_SESSION['SESS_USER_ID'];
   }

   return null;
}


/**
 * "Marks" given user id as a logged one
 * 
 * @return void
 */
function register_user_id_as_logged($id){

   //will start session also if not started yet
   if ( is_user_logged() !== TRUE ){
      $_SESSION['SESS_USER_ID'] = $id;
   }
}

これらの関数をドキュメントの先頭に配置します。

今変更:

#1 HTML テンプレート

<?php if ( TRUE === is_user_logged() ) : ?>

// Some HTML or Script if logged

<?php else : ?>

// Some HTML or Script if not logged

<?php endif; ?>

#2

...
$member = $stmt_user->fetch();                 
if($member) {                  
   $_SESSION['SESS_USER_ID'] = $member['user_id'];                 
   session_write_close(); 
   echo "true";
   exit;

に:

$member = $stmt_user->fetch();                 
if ($member) {  //<-- Somehow my heart tells me it should be - if ( isset($member[0]) )

   register_user_id_as_logged($member['user_id']); //<-- and this should be $member[0]['member_id']
   session_regenerate_id();
   exit('true');



if (data == "true") { 


$("#loginForm").fadeOut("fast"); // <-- not required if you're going to do redirect


// THIS IS WHERE I'VE TRIED TO SET $logged_in  <-- if you already in this "block", a "session id" is already set and it "works"
// all you need to do is just to redirect,like:

window.location = 'some_profile_page.php';

今、私自身の推奨事項

ヒント#1

JavaScript が無効になっていないことを確認してください。これは、次のように簡単に実行できます。

<!DOCTYPE html>
<html>
<head>

...

<!--So, when JS is disabled, it would redirect to /error.php page automatically -->
<noscript>

    <meta http-equiv="REFRESH" content="0; url=/error.php" />

</noscript> 

 ...
</head>


...
</html>


すべての HTML ドキュメントでこのトリックを使用してください。

ヒント#2

すべてのプロファイル関連のロジックをクラスにカプセル化する必要があります。これは次のようになります。

class Profile {

    private $db;

    public function __construct(PDOAdapter $db)
    {
        $this->db = $db;
    }


    public function login($username, $password)
    {
        //do query here and return boolean
    }

    public function logout()
    {
        //destroy session here
    }


    public function isLogged()
    {
        // check if session key exists and its a valid one here
    }

    private function registerAsLogged()
    {
        //....
    }
}
于 2013-01-02T18:35:20.093 に答える
1

AJAX 経由でログイン リクエストを送信する場合、メイン ページの PHP はサーバー側で既に作成されているため、影響を受けません。AJAX を介して呼び出しを行うことに行き詰まっている場合は、次のことができます。

1) success() 関数を使用して、ダイアログ/フレーム/$logged_in 変数を使用するページを更新します

2) success() 関数を使用して別の AJAX 呼び出しを行い、ページを取得します。

3)すべてをロードします(機密性に応じて)が、「ログイン済み」マテリアルを に設定し、display:none;success() を使用して次のようなことを行います$('.logged-in-user-stuff').show();

于 2013-01-02T03:27:30.107 に答える