简体   繁体   English

会话和php重定向不起作用

[英]Sessions and php redirect doesn't work

I am making a PHP script check.php that checks if a user is logged in. There is only one user, so the password is written directly in the php code. 我正在制作一个PHP脚本check.php来检查用户是否已登录。只有一个用户,所以密码直接写在php代码中。 The check.php is included at the top (line 1) of every relevant page with the line <? include "check.php"; ?> check.php包含在每个相关页面的顶部(第1行),行<? include "check.php"; ?> <? include "check.php"; ?> <? include "check.php"; ?> . <? include "check.php"; ?>

The code 代码

I have removed the password and the domain name. 我已经删除了密码和域名。 Apart from that the following is my code. 除此之外,以下是我的代码。 The point here is that you type in a password at a login page, and then send it by POST to this script. 这里的要点是您在登录页面输入密码,然后通过POST将其发送到此脚本。

If the password is correct xxx, the session login will store true . 如果密码是正确的 xxx,会话login将存储为true

If the password is not correct , but is set, meaning the user typed in something wrong, any existing session is ended with session_destroy() , meaning he is logged out. 如果密码不正确 ,但设置,这意味着在一些错误键入的用户,任何现有会话与结束session_destroy()这意味着他将被注销。

If he reaches a page but is not logged in , the session login should be false or not set, meaning that the } elseif(!($_SESSION['login'])) { will be used. 如果他到达页面但未登录 ,则会话login应为false或未设置,这意味着将使用} elseif(!($_SESSION['login'])) {

Lastly, if he clicks a logout button he is send to this script with the url: check.php?logout=true . 最后,如果他点击退出按钮,他将使用url发送到此脚本: check.php?logout=true The logout=true should be caught in the $_GET in the final elseif statement, and the session should be ended in there. logout=true应该在最后的elseif语句中的$_GET中捕获,并且会话应该在那里结束。

<?
ob_start();
session_start();


if($_POST['password'] == 'xxx') {   // Correct password

    $_SESSION['login'] = true;
    header("Location: http://www.url.com/administration/index.php");

} elseif (isset($_POST['password'])) {  // Wrong password

    session_destroy();
    header("Location: http://www.url.com/administration/login.php?true");

} elseif(!($_SESSION['login'])) {   // Check at every page

    header("Location: http://www.url.com/administration/login.php");

} elseif($_GET['logout']) { // Log out

    session_destroy();
    header("Location: http://www.url.com/");

}
ob_flush();
?>

The problem 问题

In every if statement I try to redirect. 在每个if语句中,我尝试重定向。 I use the header("Location:...) , but it doesn't work in any of the cases. Because the header command must be the first request to be send to the browser according to the specs, I used the ob_start(); and ob_flush(); as described here . It doesn't work with or without these. 我使用header("Location:...) ,但它在任何情况下都不起作用。因为header命令必须是根据规范发送到浏览器的第一个请求,所以我使用了ob_start();ob_flush();如此处所述 。无论是否有这些都无效。

Also there is a problem with the session that will not store content. 此外,会话存在无法存储内容的问题。 I can't store true in the session of some reason. 我不能在某些原因的会话中存储true Is there a problem with my code that makes it fail? 我的代码是否存在问题导致其失败?

As a test I have tried to write an echo command in every if / ifelse statement. 作为测试,我试图在每个if / ifelse语句中编写一个echo命令。 From that I found that the script always enters the third statement - the one with the !($_SESSION['login']) . 从那里我发现脚本总是进入第三个语句 - 带有!($_SESSION['login'])语句。

The question 这个问题

So far so good. 到现在为止还挺好。 This tells me that the script is able to detect that the session is not set. 这告诉我脚本能够检测到会话未设置。
The two problems that remain are: 剩下的两个问题是:

  • WHY the redirect in a statement doesn't work, since no redirect happens, and 为什么语句中的重定向不起作用,因为没有重定向发生,并且
  • WHY the session can't be set in the first place. 为什么不能首先设置会话。

Any advice will be appreciated. 任何建议将被认真考虑。


Update 1 更新1

To make it clear what happens (and what doesn't happen) I have put in some echo s at different spots. 为了清楚说明发生了什么(以及什么不发生),我在不同的地方放了一些echo This snippet of the above code with some additional echo s: 以上代码的这个片段带有一些额外的echo

...
echo "Input: " . $_POST['password'];
echo "<br>Session before: " . $_SESSION['login'];

if($_POST['password'] == 'xxxx') {  // Correct password

    $_SESSION['login'] = true;
    header("Location: http://www.url.com/administration/index.php");
    echo "<br>Session after: " . $_SESSION['login'];
    echo "<br>The first if works";

} ...

returns the following output: 返回以下输出:

Input: xxxx
Session before:
Session after: 1
The first if works

(The xxxx is the password; and it is correct.) (xxxx是密码;它是正确的。)

This is a situation where you are loggin in. You have just written the password and has been sent to the check.php . 这是您登录的情况。您刚刚写了密码并已发送到check.php

So, I can see here that it accesses the first if as it is supposed to. 所以,我可以在这里看到它if应该的那样访问第一个。 And the session is correctly set to true (or 1 ). 会话正确设置为true (或1 )。 When I refresh the page the session is not set anymore though. 当我刷新页面时,会话不再被设置。 Shouldn't it be? 不应该吗?

And the header redirect clearly doesn't do anything. header重定向显然没有做任何事情。


Update 2 更新2

So, thanks to the answer from @EmilF below, I found that my session id - which I could print to the screen with echo session_id(); 所以,感谢下面@EmilF的回答,我发现我的会话ID - 我可以用echo session_id();打印到屏幕上echo session_id(); - changes at every page shift or page refresh to some new random number it seems. - 每次页面转换或页面刷新时的更改似乎是一些新的随机数。 I looks as if the data stored in the session is then forgotten, because the new session id points somewhere else. 我看起来好像存储在会话中的数据被遗忘了,因为新的会话ID指向其他地方。

By using: 通过使用:

<?
session_id('cutckilc16fm3h66k1amrrls96');
session_start();
...

where cutckilc16fm3h66k1amrrls96 is just a random number, the session id is fixed, and the stored data can now be retrieved again after page refresh. 其中cutckilc16fm3h66k1amrrls96只是一个随机数,会话ID是固定的,现在可以在页面刷新后再次检索存储的数据。 This works quite well; 这非常有效; though still a bit odd it is necessary. 虽然有点奇怪但是有必要。

Now I only need the header redirect to work... 现在我只需要头重定向工作......

Well, this smells like something that has been shut off. 嗯,这闻起来像是被关闭的东西。 The session and the header functionality are changed. 会话和标头功能已更改。 Maybe this is some PHP setting from the host. 也许这是来自主机的一些PHP设置。 Something that blocks the header request. 阻止标头请求的东西。

To be continued... 未完待续...

Update 3 - solved 更新3 - 解决了

See my answer below. 请参阅下面的答案。

Some strange symbols are created in the beginning of the file when I change the file into another coding format, eg from ANSI to UTF-8. 当我将文件更改为另一种编码格式时,例如从ANSI到UTF-8,会在文件的开头创建一些奇怪的符号。 The symbols created are  , and I cannot see them in my own editor. 创建的符号是 ,我无法在自己的编辑器中看到它们。 Because they are in front of the php script they prevent the header and session_start() to work proporly. 因为它们位于php脚本的前面,所以它们会阻止headersession_start()以正常方式工作。 Why they are created there is still a mystery to me. 为什么它们被创造出来对我来说仍然是一个谜。

Okey, let's list everything you can debug here, mentioning also stuff you already did (so other people can read it): 哦,让我们列出你可以在这里调试的所有内容,还提到你已经做过的事情(所以其他人可以阅读):

  • Do you have something like HTTP Header installed? 你有安装HTTP Header之类的东西吗? Then you can see if the Location: header is sent to your browser or not. 然后,您可以查看是否将Location:标头发送到您的浏览器。
  • I suppose you do not get any error messages, do you? 我想你没有收到任何错误信息,对吗? Have you set error_reporting(E_ALL); 你设置了error_reporting(E_ALL); ?
  • Try doing var_dump() for the $_POST array. 尝试为$_POST数组执行var_dump()
  • Do you also have something to check cookies with in your browser? 您还有什么东西可以在浏览器中查看cookie吗? I usually use the Firefox web-developer toolbar plugin which has a menu Cookie -> show cookie information . 我通常使用Firefox web-developer工具栏插件 ,它有一个菜单Cookie - >显示cookie信息 There you should see a PHPSESSID cookie (after login). 在那里你应该看到一个PHPSESSID cookie(登录后)。 If not, your URL should include some information about the session id (looks like this: ?PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4 ). 如果没有,您的URL应包含有关会话ID的一些信息(如下所示: ?PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4 )。 Otherwise, PHP cannot find a session, because it does not know which session belongs to you. 否则,PHP无法找到会话,因为它不知道哪个会话属于您。

If this does not help check if the cookie is set: 如果这无助于检查cookie是否已设置:

  • Again open your header plugin and then perform a login. 再次打开标题插件 ,然后执行登录。 Check if the server sends a cookie to you. 检查服务器是否向您发送cookie。 This must be done in a Set-Cookie command. 这必须在Set-Cookie命令中完成。 It might look like this: Set-Cookie: PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4; path=/ 它可能如下所示: Set-Cookie: PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4; path=/ Set-Cookie: PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4; path=/
  • If the server does not set a cookie, check for the settings in php.ini . 如果服务器没有设置cookie,请检查php.ini的设置。 There must be a setting session.use_cookies = 1 which must be set to 1 or On to allow PHP to use cookies. 必须设置session.use_cookies = 1 ,必须设置为1On以允许PHP使用cookie。
  • If the server does set a cookie, but your browser does not allow it, check the options of your browser for cookies. 如果服务器确实设置了cookie,但您的浏览器不允许,请检查浏览器的cookie选项。 Also check the php.ini setting for session.use_only_cookies = 0 . 另请检查session.use_only_cookies = 0php.ini设置。 If this is set to 1 you forbid PHP to use the URL if a cookie is not accepted by the browser. 如果设置为1 ,则禁止PHP使用URL,如果浏览器不接受cookie。 This is usually forbidden for security reasons, because people copy URLs to friends and then these friends will take over the logged in session ;) So just set it to 0 for debugging purposes. 出于安全原因,这通常是被禁止的,因为人们将URL复制到朋友,然后这些朋友将接管登录的会话;)所以只需将其设置为0以进行调试。
  • var_dump() the return value of session_start() . var_dump() session_start()的返回值。 It will return false if PHP was not able to start the session correctly. 如果PHP无法正确启动会话,它将返回false。

Mystery solved here: Byte Order Mark 神秘在这里解决了: 字节顺序标记

在此输入图像描述

Best answer you will find: 你会发现最佳答案:

https://stackoverflow.com/a/8028987/424004 https://stackoverflow.com/a/8028987/424004

Try printing the PHPSESSID with session_id(). 尝试使用session_id()打印PHPSESSID。 Do you get the same output if you keep refreshing? 如果你保持清爽,你会得到相同的输出?

If not try to set the id with: session_id('cutckilc16fm3h66k1amrrls96') 如果没有尝试设置id:session_id('cutckilc16fm3h66k1amrrls96')

http://php.net/manual/en/function.session-id.php http://php.net/manual/en/function.session-id.php

It should work now, but with the same session for all users. 它现在应该工作,但所有用户使用相同的会话。

The problem could be something like this: PHP Session data not being saved 问题可能是这样的: PHP会话数据没有被保存

After many long days and nights of testing, reading and asking and with a lot of help from the participants on this question - thanks a lot for your effort! 经过许多漫长的日日夜夜的测试,阅读和询问以及参与者对此问题的大量帮助 - 非常感谢您的努力! - I slowly reached this rather mysterious solution to the problem. - 我慢慢地达成了这个相当神秘的问题解决方案。
A solution I found, but an explanation I still don't have... 我找到了一个解决方案,但我仍然没有解释......

So, as described in Update 2, I found from the answer from @EmilF that the session id changed constantly. 因此,如更新2中所述,我从@EmilF的答案中发现会话ID不断变化。 A thought was then to suspect a server / host issue. 然后想到了一个服务器/主机问题。 I contacted the host - one.com - who at first like me didn't understand, why it didn't work. 我联系了主持人 - one.com - 他最初和我一样不理解,为什么它不起作用。

But then he told me, there was some rather odd symbols in the beginning of the check.php file. 但他告诉我, check.php文件的开头有一些相当奇怪的符号。 I couldn't see them in my own editor. 我在自己的编辑器中看不到它们。 They weren't visible until I accessed the file via the FileManager software that one.com provides browser based. 在我通过one.com提供基于浏览器的FileManager软件访问文件之前,它们不可见。

The issue and solution 问题和解决方案

The top of the file looked like this: 文件的顶部看起来像这样:

<?
ob_start();
session_start();


if($_POST['password'] == 'xxx') {   // Correct password

    $_SESSION['login'] = true;
...

You can see the odd symbols  in the beginning. 你可以在开头看到奇怪的符号 As I said, they were not visible in my own editor Notepad++, nor in regular Notepad. 正如我所说,它们在我自己的编辑器Notepad ++ 中不可见,也不在常规记事本中。 I sent the file to a friend to check, and he couldn't see them either in his editor, Coda. 我将文件发送给朋友检查,他无法在他的编辑Coda中看到它们。

These symbols would of course act as output to the browser. 这些符号当然会作为浏览器的输出。 Therefor this is a request to the browser that occours before the session_start() and the header(Location:... . Because those two commands must be prior to any browser request, they don't work now in this case with the symbols present. 因此,这是对session_start()header(Location:...之前出现的浏览器的请求header(Location:...因为这两个命令必须在任何浏览器请求之前,所以在这种情况下它们现在不起作用,并且符号存在。

Sessions and header command work perfect now with the symbols removed. 现在,Sessions和header命令可以完美地删除符号。

Still no explanation... 仍然没有解释......

I have no idea why they are there, but after more testing I found out how they got there: 我不知道为什么他们在那里,但经过更多测试我发现他们是如何到达那里的:

In Notepad++ I can change the coding format in the menu. 在Notepad ++中,我可以在菜单中更改编码格式。 When I change from fx ANSI to UTF-8, the symbols have appeared. 当我从fx ANSI更改为UTF-8时,符号出现了。 In normal Notepad I can save as UTF-8 as an option in the "Save as" window. 在普通的记事本中,我可以在“另存为”窗口中将其保存为UTF-8选项。 And the symbols also appear in this case. 在这种情况下,符号也会出现。

In any case I can only see the symbols  , when I view the code through a browser based editor that takes the files directly from the server. 在任何情况下,当我通过基于浏览器的编辑器查看代码时,我只能看到符号 ,该编辑器直接从服务器获取文件。 And nomatter the editor it is always  that are created. 并且编辑总是如此

I don't have the explanation for this. 我对此没有解释。 This might be a good topic for another SO question. 对于另一个SO问题,这可能是一个很好的主题。

Thanks to all who tried to help me. 感谢所有试图帮助我的人。 I am answering the question here, because this is the answer. 我在这里回答这个问题,因为这就是答案。 But all help and debugging tricks have been much appreciated and very helpful. 但是所有帮助和调试技巧都非常受欢迎并且非常有用。

Thanks a lot and have a good summer all of you. 非常感谢,祝大家夏天愉快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM