试图了解Post / Redirect / Get设计模式(用PHP实现) [英] Trying to understand the Post/Redirect/Get design pattern (implemented with PHP)

查看:98
本文介绍了试图了解Post / Redirect / Get设计模式(用PHP实现)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部,



提前抱歉 - 我不是PHP专家或知识渊博的设计模式,所以这个问题可能有点基础...

无论如何,我正在使用一个需要登录的网络应用程序。



我的计划是像这样:



index.php:此页面将包含一个允许用户输入用户名和密码的简单表单。表单将POST输入到...



login.php:此页面将接收来自index.php的输入,并根据数据库检查这些凭据。如果任何输入丢失,或者凭据检查失败,php脚本将使用



<$ p将 REDIRECT 回到index.php $ p> 标头('位置:http://www.mydomain.com/index.php');

如果凭据有效,那么login.php会创建一个会话来建立用户的身份验证状态: / p>

  session_start(); 
$ _SESSION ['authenticated'] = true;

然后,它确定用户具有什么访问类型。如果他具有1级权限,则脚本将使用以下方式将用户重定向到level1.php:

 头('位置: http://www.mydomain.com/level1.php'); 

如果用户具有2级访问权限,则脚本将使用 :

  header('Location:http://www.mydomain.com/level2.php'); 

最后,当达到level1.php或level2.php时,他们首先要检查会话。如果用户未通过身份验证,请将其重定向到index.php:

  session_start(); 
if(!isset($ _ SESSION ['authenticated']){
header('Location:http://www.mydomain.com/index.php');
} else {
//继续显示页面
}

在level1中进行此检查.php和level2.php将阻止用户直接访问该页面,而无需登录。



我的第一个问题是这样的:这个简单的逻辑失败第一次通过 - 当level1.php到达,isset($ _ SESSION ['authenticated']始终返回false,所以用户总是重定向回index.php,如果他第二次输入完全相同的凭据,这个过程的工作原理就是这样。



简而言之,由于我不明白的原因,似乎由level1找不到login.php设置的会话。 php - 我认为是因为重定向,换句话说,对level1.php的检查似乎失败,直到/除非客户端的浏览器往返。



因为每个网站都要求你的登录已经解决了这个问题,这不应该是一个新颖的挑战,他们应该是一个非常成熟的模式。我应该如何处理?



一个相关的问题...以前我已经看过类似的问题,大多数答案通常涉及一个解决方案,其中哪些页面是POST给自己这似乎有点尴尬 - 理想情况下,我想让每个PHP页面执行一个特定的工作:




  • index.php - 显示一个表单捕获
    凭据,然后将其发布到
    login.php

  • login.php - 评估用户的
    凭据,然后将它们引导至
    适当页面

  • level1.php& level2.php - 显示
    适当的内容



这是一个有缺陷的设置?如果是这样,那么更好的设置是什么?



通常 - 如果一个页面建立一个会话,然后将用户重定向到另一个页面 - 是否有任何方式可以读取第二页会话?



维基百科上有一篇关于Post / Redirect / Get的优秀页面:



http://en.wikipedia.org/wiki/Post/Redirect/Get



但是这对我来说有一点概念 - 我想看看它对参考具体页面的解释:



例如A页上的表单将数据POST到B页,B页将用户重定向到C页等。



而且,我不了解如何使用会话实现,如果在使用重定向时无法识别会话。



非常感谢您提供任何建议和见解。






[更新]



感谢Matt Ball的评论,我已经解决了这个问题:



login.php正在设置会话并将用户重定向到下一个屏幕:

  session_start(); 
$ _SESSION ['authenticated'] = true;
header('Location:http://www.mydomain.com/level1.php');

但是,当level1.php检查该会话时,authenticated是 NOT SET

  session_start(); 
echo(isset($ _ SESSION ['authenticated']); //返回false

但是,如果我更改了login.php,以便将标题重定向到 RELATIVE 网址,而不是绝对的URL:

  session_start(); 
$ _SESSION ['authenticated'] = true;
header('Location:level1.php');
pre>

然后,level1.php的工作原理如下:

  session_start(); 
echo(isset($ _ SESSION ['authenticated']); //现在返回true

我不明白为什么相对URL有所不同,但是它是这样的,所以至少我的即时问题已经解决了。



所有人评论!






干杯,
Matt Stuehler

解决方案

发布重定向如果他们刷新已被重定向到的页面,则进入播放状态以停止用户重新发送其POST数据提交表单当您要实现PRG时,您应该将HTTP标头代码设置为303,如下所示:

  header( 'Location:level1.php',303); 


All,

Sorry in advance - I'm not a PHP expert or knowledgeable in design patterns, so this question might be a little basic...

Anyway, I'm working on a web app that will require a login.

My plan is to have something like this:

index.php: this page will contain a simple form that allows users to enter a username and password. The form will POST the inputs to...

login.php: this page will receive the inputs from index.php, and check those credentials against a database. If any of the inputs are missing, or the credentials check fails, the php script will REDIRECT the user back to index.php using:

header('Location: http://www.mydomain.com/index.php');

If the credentials are valid, then login.php creates a session to establish the user's authenticated status:

session_start();
$_SESSION['authenticated'] = true;

Then, it determines what access type the user has. If he has "level 1" access, the script will redirect the user to level1.php using:

header('Location: http://www.mydomain.com/level1.php');

If the user has "level 2" access, the script will redirect the user to level2.php using:

header('Location: http://www.mydomain.com/level2.php');

Finally, when level1.php or level2.php is reached, the first thing they do is check the session. If the user is not authenticated, redirect him back to index.php:

session_start();
if (!isset($_SESSION['authenticated']) {
    header('Location: http://www.mydomain.com/index.php');
} else {
    // proceed to display the page
}

Having this check in level1.php and level2.php will prevent users from accessing that page directly, without logging in.

My first issue is this: this simple logic FAILS the first time through - when level1.php is reached, "isset($_SESSION['authenticated']" ALWAYS returns false, so the user is always redirected back to index.php. If he enters the exact same credentials a second time, the process works as it should.

In short, for reasons I don't understand, it seems the session that's set by login.php is not found by level1.php - I assume because of the redirect. In other words, the check on level1.php seems to fail until/unless a round trip is made to the client's browser.

Since every site that requires login has already solved this problem, this shouldn't be a novel challenge, and their should be a very established pattern for it. How should I handle it?

A related question... I've seen similar questions asked here before, and most answers usually involve a solution in which pages are POSTing back to themselves. This seems a little wierd - ideally, I'd like to have each PHP page perform a specific job:

  • index.php - display a form to capture credentials, then post them to login.php
  • login.php - evaluate the user's credentials, then direct them to the appropriate page
  • level1.php & level2.php - display the appropriate content

Is this a flawed setup? If so, what's the better setup?

And generally - if one page establishes a session, then redirects the user to another page - is there any way that second page can read the session?

There's a great page on Wikipedia about Post/Redirect/Get:

http://en.wikipedia.org/wiki/Post/Redirect/Get

But it's a little conceptual for me - I'd like to see it explained with references to specific pages:

E.g. a form on "page A" POSTs data to "page B", "page B" redirects the user to "page C", etc...

And, I don't understand how it's implemented with sessions, if sessions aren't recognized when using redirects.

Many thanks in advance for any advice and insights.


[UPDATE]

Thanks to Matt Ball's comment, I've refined the issue:

login.php was setting the session and redirecting the user to the next screen:

session_start();
$_SESSION['authenticated'] = true;
header('Location: http://www.mydomain.com/level1.php');

However, when level1.php checked that session, "authenticated" was NOT SET:

session_start();
echo (isset($_SESSION['authenticated']); // returns false

However, if I changed login.php so that the header redirected to a RELATIVE url instead of an absolute one:

session_start();
$_SESSION['authenticated'] = true;
header('Location: level1.php');

Then, level1.php works like I expect:

session_start();
echo (isset($_SESSION['authenticated']); // now returns true

I don't understand why the relative URL makes a difference, but it does. So, at least my immediate issue is resolved.

Many thanks to everyone who commented!


Cheers, Matt Stuehler

解决方案

Post Redirect Get comes in to play to stop a user resending their POST data if they refresh the page they've been redirected to after submitting a form. When you want to implement a PRG, you should set the HTTP header code to 303 like this:

header('Location: level1.php', 303);

这篇关于试图了解Post / Redirect / Get设计模式(用PHP实现)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆