<noframes id="7xbfr"><pre id="7xbfr"><output id="7xbfr"></output></pre>

      <big id="7xbfr"><font id="7xbfr"><listing id="7xbfr"></listing></font></big>
        <p id="7xbfr"></p>
        <menuitem id="7xbfr"></menuitem>

          <video id="7xbfr"><mark id="7xbfr"><listing id="7xbfr"></listing></mark></video>
            <form id="7xbfr"></form>

          <delect id="7xbfr"><var id="7xbfr"></var></delect>

          結合PHP TP6 實現 jwt 登陸驗證實例

          時間:2021-08-21 16:31:12 類型:PHP
          字號:    

          JWT優勢與不足, 這里就再細說了, 大家可以登陸某度, 實勁搜, 有存在, 必然有價值, 這里就結合tp6及html前端來個實例, 當然, 現在前端比較流行vue, 其實道理是一樣的, 用vue的話, 你只要把 token 永久保存即可, 比如通過localStorage或者vuex等

          廢話不多說了, 直接上代碼了

          1, JWT類文件Jwt.php, 我把它放在extend目錄下, 方便 調用 

          <?php 
          /**
           * PHP實現jwt
           */
          class Jwt {
          
              //頭部
              private static $header=array(
                  'alg'=>'HS256', //生成signature的算法
                  'typ'=>'JWT'    //類型
              );
          
              //使用HMAC生成信息摘要時所使用的密鑰
              private static $key='asdf_wr@#&(*@#$&#(@_@#)$#@$_!23kasdf';
          
          
              /**
               * 獲取jwt token
               * @param array $payload jwt載荷   格式如下非必須
               * [
               *  'iss'=>'jwt_admin',  //該JWT的簽發者
               *  'iat'=>time(),  //簽發時間
               *  'exp'=>time()+7200,  //過期時間
               *  'nbf'=>time()+60,  //該時間之前不接收處理該Token
               *  'sub'=>'www.admin.com',  //面向的用戶
               *  'jti'=>md5(uniqid('JWT').time())  //該Token唯一標識
               * ]
               * @return bool|string
               */
              public static function getToken(array $payload)
              {
                  if(is_array($payload))
                  {
                      $base64header=self::base64UrlEncode(json_encode(self::$header,JSON_UNESCAPED_UNICODE));
                      $base64payload=self::base64UrlEncode(json_encode($payload,JSON_UNESCAPED_UNICODE));
                      $token=$base64header.'.'.$base64payload.'.'.self::signature($base64header.'.'.$base64payload,self::$key,self::$header['alg']);
                      return $token;
                  }else{
                      return false;
                  }
              }
          
          
              /**
               * 驗證token是否有效,默認驗證exp,nbf,iat時間
               * @param string $Token 需要驗證的token
               * @return bool|string
               */
              public static function verifyToken(string $Token)
              {
                  $tokens = explode('.', $Token);
                  if (count($tokens) != 3)
                      return false;
          
                  list($base64header, $base64payload, $sign) = $tokens;
          
                  //獲取jwt算法
                  $base64decodeheader = json_decode(self::base64UrlDecode($base64header), JSON_OBJECT_AS_ARRAY);
                  if (empty($base64decodeheader['alg']))
                      return ["code"=>2, "mes"=>"算法錯誤"];
          
                  //簽名驗證
                  if (self::signature($base64header . '.' . $base64payload, self::$key, $base64decodeheader['alg']) !== $sign)
                      return ["code"=>3,"mes"=>"簽名錯誤"];
          
                  $payload = json_decode(self::base64UrlDecode($base64payload), JSON_OBJECT_AS_ARRAY);
          
                  //簽發時間大于當前服務器時間驗證失敗
                  if (isset($payload['iat']) && $payload['iat'] > time())
                      return ["code"=>4,"mes"=>"簽發時間不對"];
          
                  //過期時間小于當前服務器時間驗證失敗
                  if (isset($payload['exp']) && $payload['exp'] < time())
                      return ["code"=>5,"mes"=>"已經過期"];
          
                  //該nbf時間之前不接收處理該Token
                  if (isset($payload['nbf']) && $payload['nbf'] > time())
                      return ["code"=>6,"mes"=>"非處理token時間"];
          
                  return ["code"=>1, "payload"=>$payload];
              }
          
          
          
          
              /**
               * base64UrlEncode   https://jwt.io/  中base64UrlEncode編碼實現
               * @param string $input 需要編碼的字符串
               * @return string
               */
              private static function base64UrlEncode(string $input)
              {
                  return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
              }
          
              /**
               * base64UrlEncode  https://jwt.io/  中base64UrlEncode解碼實現
               * @param string $input 需要解碼的字符串
               * @return bool|string
               */
              private static function base64UrlDecode(string $input)
              {
                  $remainder = strlen($input) % 4;
                  if ($remainder) {
                      $addlen = 4 - $remainder;
                      $input .= str_repeat('=', $addlen);
                  }
                  return base64_decode(strtr($input, '-_', '+/'));
              }
          
              /**
               * HMACSHA256簽名   https://jwt.io/  中HMACSHA256簽名實現
               * @param string $input 為base64UrlEncode(header).".".base64UrlEncode(payload)
               * @param string $key
               * @param string $alg   算法方式
               * @return mixed
               */
              private static function signature(string $input, string $key, string $alg = 'HS256')
              {
                  $alg_config=array(
                      'HS256'=>'sha256'
                  );
                  return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));
              }
          }
           ?>

            建立登陸控制器JwtController.php

             訪問登陸頁面:

          public function loginTest(){
                  return View::fetch('login');
              }

             登陸視圖:

           <form style="width: 300px; margin: 0 auto;">
          		  <li>
          			   <input type="text" name="username" placeholder="用戶名">
          		  </li>
          		  <li>
          			   <input type="password" name="userpwd" placeholder="用戶密碼">
          		  </li>
          		  <li>
          			   <input type="button" value="登陸" id="login">
          		  </li>
          	 </form>
          	 <script type="text/javascript">
          	 	  $(function(){
          	 	  	  $("#login").on("click", function(){
          	 	  	  	     let username = $("input[name='username']").val();
          		 	  	     let userpwd  = $("input[name='userpwd']").val();
          		 	  	     $.post("/jwt/loginCheck", { "username": username,"userpwd" : userpwd },function(data){
          			         		if(data.code == 1){
          			         			localStorage.setItem("token",data.token);
          			         			//將token在客戶端存儲起來, 服務器端不存儲任何信息
          			         			//好處: 多點登錄非常方便(服務器段不用每個服務器, 每個站點都存儲用戶信息)
          			         			//壞處: 一經簽發, 在到期之前就會始終有效,除非服務器部署額外的邏輯
          			         		}
          			          }, "json");
          		 	  	    })
          	 	  	 
          	 	  })
          	 </script>

          登陸檢查及生成token

           public function loginCheck(){
                  $post = $this->request->post();
                  //模擬比較, 實際應用中通常 從數據庫中查詢比對
                  if($post["username"] == "admin" && $post["userpwd"] == "123456"){
                       $payload=[
                          'iss'=>'莊子',
                          'iat'=>time(),
                          'exp'=>time()+7200,
                          'nbf'=>time(),
                          'sub'=>'用戶登陸操作',
                          'jti'=>md5(uniqid('JWT').time()),
                          "username"=>$post["username"]
                      ];
                      $token=\Jwt::getToken($payload);
                      return json(["code"=>1, "mes"=>"登陸成功","token"=>$token]);
                  }
              }

            驗證是否登陸或者過期視圖:

          $(function(){
          	 	  	         if(localStorage.getItem("token") != ""){
          	 	  	         	 $.post("/jwt/jwtverify", 
          	 	  	         	 		{ "token": localStorage.getItem("token")},
          	 	  	         	 	   	function(data){
          	 	  	         	 	   		if(data.code == 1){
          	 	  	         	 	   			console.log("驗證成功");
          	 	  	         	 	   		}
          	 	  	         	 	   		else{
          	 	  	         	 	   			console.log("驗證失敗  ");
          	 	  	         	 	   		}
          	 	  	         	 	   	},
          	 	  	         	 	    "json");
          	 	  	         }
          	 	  	         //或者通過 在 HTTP 請求的頭信息Authorization字段里面 如下
          			         /* if(localStorage.getItem("token") != ""){
          	 	  	         	 $.ajax({
          	 	  	         	 	 "url" : "/jwt/jwtverify1",
          	 	  	         	 	 "dataType":"json",
          	 	  	         	 	 success:function(data){
          	 	  	         	 	 	if(data.code == 1){
          	 	  	         	 	   			console.log("驗證成功");
          	 	  	         	 	   		}
          	 	  	         	 	   		else{
          	 	  	         	 	   			console.log("驗證失敗  ");
          	 	  	         	 	   		}
          	 	  	         	 	 },
          	 	  	         	 	 beforeSend : function(request) {
          								request.setRequestHeader("Authorization", localStorage.getItem("token"));
          							},
          	 	  	         	 })
          	 	  	         }
          	 	  	         */
          	 	  	         //tp服務端接收方法 : $this->request->header("Authorization");
          	 	  	 
          	 	  })

          對token進行驗證

           public function jwtverify(){
                  if(!$this->request->post("token")){
                       return View::fetch();
                  }
                  else{
                      //對token進行驗證簽名
                      $result = \Jwt::verifyToken($this->request->post("token"));
                      if($result["code"] == 1){
                          return json(["code"=>1,"mes"=>"success", "username"=>$result["payload"]["username"]]);
                      }
                      else{
                          return json(["code"=>2,"mes"=>"fail"]);
                      }
                  }
                 
              }
              public function jwtverify1(){
                  //在請求頭時接收方法
                  return $this->request->header("Authorization");
                 
              }

          注意: 默認沒有Authoriztaion信息, 修改下.htaccess文件

           Options +FollowSymlinks -Multiviews
            RewriteEngine On
          
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
             #增加如下內容
            SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0


          黄网站免费 <