專題製作一-上課補充教材


會員的登入系統
  1. 會員的登入需要注意的項目:與註冊相同,你登入的某個資訊一定要限制一下才行!
    1. 跟註冊類似,『帳號』需要事先規範英文數字等限制比較妥當!避免被 SQL injection 攻擊
    2. 注意密碼已經使用了 sha256 (hash('sha256',$pw)) 喔!
    3. 除了防呆之外,還是注意一下註冊機器人,所以驗證碼的限制還是直接取用吧!
    4. 最好做成模組,這樣隨時都能夠被取用喔!
  2. 開始建立登入的畫面
    1. 因為登入未來可能會加在側邊欄,所以,預計使用一個『模組』即可,未來可以讓其他的頁面來呼叫!
    2. 這裡先設計放在一個位置,未來則需要將登入模組與登入畫面分別放在不同的檔案內來呼叫較佳。
    3. 登入畫面暫時放在 login.php,盡可能讓登入畫面簡潔一點。
      $ vim login.php
      <?php
      	session_start();			// 持續來使用驗證碼的功能!做成模組,這裡就有用處了!
              include ('include/captcha.php');
      ?>
      <!doctype html>
      <html>
      <head>
              <meta charset='utf-8' />
      </head>
      <body>
      
      <form id="loginform" onsubmit="return checkinput()" method="post"
              style="width: 270px; border: 1px solid gray; padding: 5px; text-align: center;">
      <table style="text-align: left;">
              <tr>
                      <td>登入帳號:</td>
                      <td><input type="text" name="login_name" required="required" id='login_name' style="width: 150px"/></td>
              </tr>
              <tr>
                      <td>登入密碼:</td>
                      <td><input type="password" name="login_pass" required="required" id='login_pass' style="width: 150px"  /></td>
              </tr>
              <tr>
                      <td>驗證碼:</td>
                      <td>
                              <img src="images/check.png" style="vertical-align: middle; "/>
                              <input type="text" name="checking" style="width: 75px" />
                      </td>
              </tr>
              <tr>
                      <td colspan="3" style="text-align:center; ">
                              <input type="hidden" name="action" value="login" />
                              <input type="submit" value="登入" />
                      </td>
              </tr>
      
      </table>
      </form>
      <script>
              function checkinput() {
                      // 檢查登入帳號是否有特殊字元
                      var re = /[^a-zA-Z0-9.-_]/;
                      var okname = re.exec ( document.getElementById("login_name").value);
                      if ( okname ) {
                              window.alert ( "只允許英文、數字、底線、小數點與減號" );
                              document.getElementById("login_name").focus();
                              return false;
                      }
      
                      // 開始檢查密碼長度是否正確?
                      var pw = document.getElementById("login_pass");
                      if ( pw.value.length < 5 ) {
                              window.alert ( "密碼長度必須要大於 5 個字元以上" );
                              document.getElementById("login_pass").focus();
                              return false;
                      }
              }
      
      </script>
      
      </body>
      </html>
      
  3. 開始實做登錄流程
    1. 登入流程中,首先要判斷是否有 action 是 login 的狀態,若是,才開始登入的檢驗。
    2. 進入登入流程檢驗之後,進行如下的判斷流程:
      1. 先檢查驗證碼,若驗證碼正確,則下一步,否則直接回傳錯誤,並回到登入畫面
      2. 開始取得帳號與密碼,並將密碼編碼
      3. 以上述資訊來與資料庫同時比對,比對正確則直接跳到下一關,否則直接回傳錯誤,並回登入畫面
      4. 登入正確給予 $_SESSION[username] 與 $_SESSION[userlevel] 兩個項目,作為未來判斷帳號之用
      5. 不要顯示登入畫面,而是顯示使用者資訊才對!
    3. 開始來實做整個 PHP 的程式碼:
      $ vim login.php
      <?php
              session_start();
              include ('include/config.php');
              if ( isset ( $_REQUEST['action'] ) ) {
                      if ( $_REQUEST['action'] == 'login' ) {
                              // 先取得所有的參數
                              $checking = $_REQUEST['checking'];
                              $login_name  = trim($_REQUEST['login_name']);   // trim 在去除一段文字的頭尾空白(包括 ENTER)
                              $login_pass  = trim( hash ('sha256', $_REQUEST['login_pass']));
      
                              // 先設定一個名為 msg 的變數,這個變數內容如果是空的,代表沒有錯誤,若非為空,則是有錯誤!
                              $msg = '';
      
                              // 先確認是否取得正確的註冊驗證碼
                              if ( $_SESSION['CAPTCHA'] != $checking ) {
                                      $msg = '驗證碼錯誤!請重新取得正確的驗證碼資訊';
                              } else {
                                      // 開始取得帳號與密碼
                                      $sql = "select login_name, realname from userinfo where login_name = '$login_name' and login_pass = '$login_pass'";
                                      $result = mysql_query ($sql, $db_link );
      				$usernu = mysql_num_rows($result);
                                      if ( $usernu < 1 ) {
                                              // 找不到資料的結果,就是給予錯誤訊息
                                              $msg = '查不到這個帳號或密碼錯誤';
                                      } else {
                                              $row = mysql_fetch_row($result);
                                              $_SESSION['username'] = $row[1];
                                              $_SESSION['userlevel'] = 'user';
                                      }
                              }
                      }
              }
      
              include ('include/captcha.php');
      ?>
      <!doctype html>
      .....
              <tr><td colspan="2" ><?php if ( $msg != '' ) echo $msg ?></td></tr>
              <tr>
                      <td colspan="3" style="text-align:center; ">
                              <input type="hidden" name="action" value="login" />
                              <input type="submit" value="登入" />
                      </td>
              </tr>
      
      </table>
      </form>
      .....
      
    4. 上述流程中,如果登入錯誤時,帳號資訊並沒有繼續留下來,有點詭異~我們修改一下這個防呆項目:
      $ vim login.php
      .....
                      <td>登入帳號:</td>
                      <td><input type="text" name="login_name" required="required" id='login_name' style="width: 150px"
                              <?php if ( isset ($login_name) ) echo "value='$login_name'" ?> /></td>
      .....
      
    5. 你會發現,即使已經登入了,還是會出現登入資訊...這不對啊!所以開始使用判斷式:
      1. 當 $_SESSION['username'] 存在時,代表使用者登入了,這時就不要顯示登入畫面
      2. 承上,那顯示的資訊就變成使用者參數說明了!
      依舊使用 PHP 的 if ... else 功能即可!
      $ vim login.php
      .....
              if ( ! isset( $_SESSION['username'] ) ) {		// 同樣的,如果沒有登入才需要取得驗證碼的模組啊!
                      include ('include/captcha.php');
              }
      .....
      <body>
      
      <?php
              if ( ! isset ( $_SESSION['username'] ) ) {
      ?>
      <form id="loginform" onsubmit="return checkinput()" method="post"
              style="width: 270px; border: 1px solid gray; padding: 5px; text-align: center;">
      .....
      </script>
      
      <?php   } else { ?>
      <div style="width: 270px; border: 1px solid gray; padding: 5px; text-align: center;">
              親愛的<?php echo $_SESSION['username'] ?>!歡迎光臨!
      </div>
      
      <?php   } ?>
      
      </body>
      </html>
      
    6. 接下來,你會發現到雖然已經登入了,不過,卻沒有登出的畫面!這不合理~因此,再加上一個登出的資訊。
      $ vim login.php
      .....
              親愛的<?php echo $_SESSION['username'] ?>!歡迎光臨!<br />
              <div style="text-align:right;">
                      <a style="text-decoration: none; color: blue;" href="<?php echo $_SERVER['PHP_SELF']; ?>?action=logout">按我登出</a>
              </div>
      </div>
      .....
      
      
    7. 其實登出流程還挺笨的,就是將 $_SESSION['username'] 與 $_SESSION['userlevel'] 的設定取消,這樣就沒有跟伺服器註冊 (SESSION 功能), 所以就會直接跳到登入的畫面中囉!
      $ vim login.php
              session_start();
              include ('include/config.php');
              if ( isset ( $_REQUEST['action'] ) ) {
                      if ( $_REQUEST['action'] == 'login' ) {
                              // 先取得所有的參數
      .....
                      }
                      if ( $_REQUEST['action'] == 'logout' ) {
                              unset($_SESSION['username']);
                              unset($_SESSION['userlevel']);
                              $urltmp = explode('?',$_SERVER['PHP_SELF']);
                              $url    = $urltmp[0];
                              echo "<script>window.location = '$url'</script>";
                              die;
                      }
              }
      
      
Top
HOME