程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了在内置服务器中指定 PHP 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决在内置服务器中指定 php 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求?

开发过程中遇到在内置服务器中指定 php 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求的问题如何解决?下面主要结合日常开发的经验,给出你关于在内置服务器中指定 php 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求的解决方法建议,希望对你解决在内置服务器中指定 php 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求有所启发或帮助;

我正在生成一个唯一的令牌并将其保存在每个请求的会话变量中(以典型的 CSRF 保护方式)。令牌在使用 POSTED 令牌值检查验证后刷新。

这是我的代码(index.php):

// index.HTML

<script src="https://unpkg.com/detect-file-enCoding-and-language/umd/language-enCoding.min.Js"></script>

当我使用 // app.Js languageEnCoding(filE).then(fileInfo => console.log(fileInfo)); // Possible result: { language: english,enCoding: UTF-8,confIDence: { language: 0.96,enCoding: 1 } } 运行脚本时,它运行良好。但是当我指定像 <?php session_start(); if (!empty($_POST['token'])) { var_dump($_POST['token'],$_SESSION['token']); exit; } $_SESSION['token'] = rand(); echo '<form action="index.php" method="post"><input name="token" value="' . $_SESSION['token'] . '"></form>'; 这样的 index.php 文件时,php -S localhost:8888 被改变了。 (php -S localhost:8888 index.php$_SESSION['token'] 不匹配)。

$_POST['token']

before after

$_SESSION['token']

before after

我也尝试过使用路由文件。它也不起作用。 php -S localhost:8888

php -S localhost:8888 index.php

控制台输出:

php -S localhost:8888 server.php

<?php
// server.php

$uri = parse_url($_SERVER['requEST_URI'],php_URL_PATH);
$uri = urldecode($uri);

if ($uri !== '/' and file_exists($uri))
{
    return false;
}

require_once 'index.php';

php -S localhost:8888

php -S localhost:8878 
[Mon Mar 29 11:49:49 2021] php 8.0.3 Development Server (http://localhost:8878) started 
[Mon Mar 29 11:49:52 2021] [::1]:47410 Accepted 
[Mon Mar 29 11:49:52 2021] [::1]:47412 Accepted 
[Mon Mar 29 11:49:52 2021] [::1]:47410 [200]: GET / 
[Mon Mar 29 11:49:52 2021] [::1]:47410 Closing 
[Mon Mar 29 11:49:53 2021] [::1]:47412 [404]: GET /favicon.ico - No such file or directory 
[Mon Mar 29 11:49:53 2021] [::1]:47412 Closing

测试使用:

php -S localhost:8888 server.php

php -S localhost:8858 server.php
[Mon Mar 29 11:48:51 2021] php 8.0.3 Development Server (http://localhost:8858) started 
[Mon Mar 29 11:48:53 2021] [::1]:33156 Accepted 
[Mon Mar 29 11:48:53 2021] [::1]:33158 Accepted 
[Mon Mar 29 11:48:53 2021] [::1]:33156 Closing 
[Mon Mar 29 11:48:54 2021] [::1]:33158 Closing

这是 php 内置服务器的错误吗?

解决方法

路由文件

这是由于您在命令中将选项设置为 php: you set the routIng file to be index.php`...

php -S localhost:8888 index.php
                      ^^^^^^^^^

...这意味着每个请求都将首先通过该文件,然后再决定要做什么。例如,假设我们的 index.php 文件包含以下内容:

if (rand(1,100) % 2) {
    echo "Not a multiple of 2\n";
    return true;
} else {
    echo "Multiple of 2\n";
    return false;
}

注意:技术上不需要return true;,但为了清楚起见,我将其包括在内

这里发生的是发出请求并运行路由文件。如果路由文件返回 false(即 2 的倍数),则请求将传递到请求的文件。如果代码返回 true,则执行停止并且请求的文件未被访问。

在您的情况下,请求的文件是 index.php(同一个文件),因此,使用上述代码,您将始终得到如下输出:

Not a multiple of 2

// OR

Multiple of 2
Multiple of 2

// OR 

Multiple of 2
Not a multiple of 2

使用您的代码/设置分解 http 请求

所以,看看你的实际代码......

session_start();

if (!empty($_POST['token'])) {
    var_dump($_POST['token'],$_SESSION['token']);
    exit;
}

$_SESSION['token'] = rand();

echo '<form ...>...</form';

这里发生了什么?

  1. 您请求 index.php*
  2. 服务器访问路由文件index.php来决定做什么
  3. 路由文件输出的数据有效地表明true
  4. 返回路由文件中的数据(表单)并且设置了 SESSION 变量
    • 对文件的请求被忽略
  5. 您提交表单
  6. 请求通过路由文件来决定要做什么(不是属性 action** 的位置)
  7. 路由文件根据 POST>token 检查 SESSION>token
  8. 它们应该匹配,因此路由文件有效地输出表明true***
  9. 返回数据
    • 对文件的请求(来自 action 属性)被忽略

* 您尝试访问的文件有 0 个不同;用 infkdsngfdslghfdslgnfdg.php 试试,它仍然会以同样的方式工作。您请求的文件从未被访问过,这只是因为请求的文件和路由的文件是相同的!

** 如上,你几乎可以将 action 属性设置为任何东西,试试 fdsfnldgksdf.php

*** 令牌是否匹配路由文件仍然输出等于true

根据 @brombeer 的测试,这确实按预期工作,那么为什么它不适合您?

问题

如果您检查运行服务器的命令提示符/终端,您会得到正在发生的事情的流(例如,当请求被接受时等)。@R_801_8462@,如果您在提出请求时观察它,您会得到如下结果:

[DATE] [::1]:XXX01 Accepted
[DATE] [::1]:XXX02 Accepted
[DATE] [::1]:XXX01 Closing
[DATE] [::1]:XXX02 Closing

@brombeer 另一方面会得到如下结果:

[DATE] [::1]:XXX01 Accepted
[DATE] [::1]:XXX01 Closing

这就是问题所在。您正在向 @brombeer 的一个请求发出两个请求,并且两个请求都通过路由文件。

第一个请求是您期望的请求,并且您会得到您期望的输出。但是,在您收到该输出后,第二个请求将运行(遵循与上述完全相同的流程 - 请记住,请求什么 file 无关紧要,脚本将输出相同的内容(!) -并有效地将 $_SESSION["token"] 更改为新的随机数。

如果你改变,这也许更容易看到......

$_SESSION["token"] = rand();

...到...

$_SESSION["token"]++;

第二个请求是什么?

这与php无关;这一切都与您的浏览器有关。浏览器对请求的文件以外的各种事物发出请求。例如:

  • JavaScript 文件
  • CSS 文件
  • 页面上使用的图片

当然,在这个例子中你没有使用任何一个。但是,浏览器会查看一些资源,看看您是否告诉他们:通常基于上下文。

在这种情况下,您的浏览器足够智能,可以知道您正在尝试访问某个网站(可能是因为端口号,也可能是因为请求方法或 URI)。

因此它会尝试定位一些它希望在网站上找到的其他文件,特别是:favicon.ico(您应该能够在浏览器的开发工具中的 Network 下看到此请求)。

如前所述,因为您已使用路由文件设置服务器,该请求与 index.phpfnjksgjfndsglkjnsf.php 请求经过完全相同的过程。事实上,甚至从未寻找过实际的图标文件。

您可以通过将此代码添加到文件顶部来进一步证明这一点...

if (!strpos($_SERVER["requEST_URI"],".php")) {
    return false;
}

如果请求的文件不是 php 文件,这将停止在您的路由文件中执行。此外,因为我们返回 false,服务器将查找图标文件。返回 true 也可以,但不会查找图标文件。

您也可以尝试将端口更改为 :8030 之类的内容,我希望代码会按您的预期工作(因为浏览器不会请求图标)。

解决办法

回到我对这个问题的第一条评论......

在这种情况下,为什么要将文件传递给服务器?

我仍然不确定您为什么这样做:我认为这是因为您不了解路由文件的作用?或者您可能不明白您正在创建路由文件?

希望我们已经解决了这个问题?

无论哪种方式,我都相当肯定设置 routIng file 不是您想要的,而且就您的目的而言,它似乎也不是您所需要的。

所以不要在命令末尾添加 index.php


额外的工作示例

将您的 index.php 替换为以下代码:

session_start();

echo "<pre>";

if (!empty($_POST['token'])) {
    var_dump($_POST['token'],$_SESSION['token']);
    exit;
}

$_SESSION['token']++;

echo '<form action="indasdasfdex.php" method="post"><input name="token" value="' . $_SESSION['token'] . '"><input type="submit" value="submit"></form>';

var_dump($_POST['token'] ?? null,$_SESSION['token'] ?? null);

使用 index.php 作为路由器文件运行您的服务器(根据您的原始问题):

php -S localhost:8888 index.php

// Because you require `index.php` in your `server.php`
// this will work the same if you use `server.php` instead

这是怎么回事

请求:index.php

Router file runs `$_SESSION["token"] == 1`
Router file returns data to browser with a form: `"token" == 1`
request terminated
Browser shows returned data
    Form: `token.value == 1`
    `var_dump` output
        `$_POST["token"] == null`
        `$_SESSION["token"] == 1`

请求:favicon.ico

Router file runs `$_SESSION["token"] == 2`
Router file returns data to browser with a form `"token" == 2`
request terminated
Browser doesn't show returned data (but you can see it in dev tools)
    _Not shown because an image isn't returned!_
    _Can be seen in dev tools_
    Form: `token.value == 2`
    `var_dump` output
        `$_POST["token"] == null`
        `$_SESSION["token"] == 2`

请求:将表单提交给index.php

Router file runs
    Dumps `$_SERVER["token"]` and `$_POST["token"]` (2,1)
Router file `exit`
request terminated
Browser shows returned data
    `var_dump` output
        `$_POST["token"] == 1`
        `$_SESSION["token"] == 2`

请求:favicon.ico

Router file runs `$_SESSION["token"] == 3`
Router file returns data to browser with a form `"token" == 3`
request terminated
Browser doesn't show returned data (but you can see it in dev tools)
    _Not shown because an image isn't returned!_
    _Can be seen in dev tools_
    Form: `token.value == 3`
    `var_dump` output
        `$_POST["token"] == null`
        `$_SESSION["token"] == 3`**

大佬总结

以上是大佬教程为你收集整理的在内置服务器中指定 PHP 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求全部内容,希望文章能够帮你解决在内置服务器中指定 PHP 文件时,在验证之前更改随机 $_SESSION 令牌 使用您的代码/设置分解 http 请求所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。