I am making a simple oauth site.
In index.php:
<?php
session_start();
if (empty($_SESSION['authentication']))
$_SESSION['authentication'] = 'pending';
?>
<html>
<form action="oauth.php" method="post">
<span>
<?php
echo $_SESSION['authentication'];
?>
</span>
<input type="hidden" name="action" value="authenticate">
<input type="submit" value="authenticate">
</form>
</html>
In oauth.php:
<?php
session_start();
if (isset($_POST['action']) and $_POST['action'] == 'authenticate') {
$url = $serverAuth ... ;
header('Location: ' . $url); //google oauth, it will come back to oauth.php
exit();
}
if (isset($_GET['code'])) {
$ch = curl_init($serverToken);
$result = curl_exec($ch);
$tokens = json_decode($result, true);
if (isset($tokens['access_token'])) {
$_SESSION['authentication'] = 'good';
$_SESSION['access_token'] = $tokens['access_token'];
} else {
$_SESSION['authentication'] = 'error';
}
header('Location: ./');
exit();
}
if (isset($_GET['error'])) {
if ($_GET['error'] == 'access_denied')
$_SESSION['authentication'] = 'denied';
else
$_SESSION['authentication'] = 'error';
header('Location: ./');
exit();
}
?>
I want to make the site like: by default, $_SESSION['authentication'] is "pending"; when I refresh the page, every session variables are gone, and $_SESSION['authentication'] reset to default. But I cannot reset $_SESSION at the beginning of index.php, because functions in oauth.php have header() to redirect to this page.
How to deal with it?
You must start the session on every single page that requires access to $_SESSION. Only destroy it when explicitly requested, e.g. on logout.
Related
Pretty simple setup: When the page is loading, a random session token is generated and saved in $_SESSION["token"]. A Form contains this token in a hidden input field. No problems until this point. I submit the form to the very same page (action="") and then I try to check if the $_SESSION["token"] is equal to the token that has been sent via POST. A variable is changed accordingly, and then I generate a new session token that replaces the old $_SESSION["token"] before the page loads again.
Problem is: The $_SESSION["token"] is changed again the moment the page is called (Before I can compare both SESSION and POST tokens) Therefore, both tokens never match. And I can't figure out WHY it changes. It's not the lines of code I wrote, because these are executed aswell, replacing the random token of unknown origin once again, before the page loads.
INDEX:
<?php
session_start();
date_default_timezone_set("Europe/Berlin");
$BASE_URL = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$form_valid = false;
if (isset($_POST["token"]) && isset($_SESSION["token"])) {
if ($_POST["token"] == $_SESSION["token"]) {
$form_valid = true;
}
}
//Set (new) session token
$token = bin2hex(random_bytes(10));
$_SESSION["token"] = $token;
//Load actual page
include ("/backend/admin.php");
?>
INCLUDED PAGE:
<?php echo "FORM VALID:"; var_dump($form_valid); ?>
<?php if (!isset($_SESSION["admin"]) || !$_SESSION["admin"]) { ?>
<form id="verify" method="POST" action="">
<label>Password</label>
<input type="password" name="access">
<input type="hidden" name="token" value="<?= $_SESSION['token'] ?>">
<input type="submit" value="Senden">
</form>
<?php } else { ?>
...
<?php } ?>
any help is appreciated. thank you.
There was a problem in your logic, session token updates every time regardless the form is submitted is not,
$token = bin2hex(random_bytes(10));
$_SESSION["token"] = $token
Try this,
<?php
session_start();
date_default_timezone_set("Europe/Berlin");
$BASE_URL = "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$form_valid = false;
if(empty($_SESSION["token"] )){
$_SESSION["token"]= bin2hex(random_bytes(10));
}
if (isset($_POST["token"]) && isset($_SESSION["token"]))
{
if ($_POST["token"] == $_SESSION["token"]) {
$form_valid = true;
unset($_SESSION["token"]);
}
}
include ("/backend/admin.php");
?>
I'm really lost here while trying to send a session with my jquery ajax post call, here is a simplified example of my code.
File fom which request is sent:
<?php
session_start();
$token = md5(rand(1000,9999));
$_SESSION['contactToken'] = $token;
?>
<script type="text/javascript">
$.post(ContactUrl,{req:"contact_sub",tok:"<?php echo $token; ?>"},function(contactAns){
alert(contactAns); return false;
});
</script>
File request is sent to:
<?php
if(#isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER']=="url"){
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) ){
session_start();
$token = $_POST['tok'];
$sess_token = $_SESSION['contactToken'];
if($token == $sess_token){
echo "sessions match"; exit();
}
else{
echo "sessions does not match"; exit();
}
}
else{echo "error"; exit();}
}
else{echo "error"; exit();}
?>
At first the session was not getting recognized, I made all the checks - made sure it was setup in the first place made sure it was posted, declared session start on both pages, never the less if i tried to do this on the second file:
<?php
session_start();
$token = $_POST['tok'];
$sess_token = $_SESSION['contactToken'];
print_r($_SESSION['contactToken']); exit();
?>
I would get an empty alert. Then I transferred the session start to the top of my script on the second page and started getting a value for the session:
<?php
session_start();
$sess_token = $_SESSION['contactToken'];
if(#isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER']=="url"){
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) ){
$token = $_POST['tok'];
echo "$token, $sess_token"; exit();
}
else{echo "error"; exit();}
}
else{echo "error"; exit();}
?>
And what I'm getting now is that the posted variable changes each time I refresh the page but the $sess_token always gives me the same value: 0589dd536fd043ff3865f8223fef3030
I really dont understand this wierd behavior, can some one please assist me with this?
Your problem here is that you're using a PHP var in an JS script without wraping and echoing it.. Here is your code modified:
You're also trying to contatenate with . in JS. That's from PHP too.
<script type="text/javascript">
$.post(ContactUrl, {
req: "contact_sub",
tok: "<?php echo $token; ?>"
}, function(contactAns) {
alert(contactAns);
return false;
});
</script>
Update
I came back to this answer again today. This is what I did:
FILE: index.php
<?php
session_start();
$token = md5(rand(1000,9999));
$_SESSION["contactToken"] = $token;
?>
<script type="text/javascript">
$.post("myOtherScript.php", {
req:"contact_sub",
tok:"<?php echo $token; ?>"
}, function(contactAns){
alert(contactAns);
return false;
});
</script>
FILE: myOtherScript.php
<?php
session_start();
$sess_token = $_SESSION["contactToken"];
if(isset($_SERVER["HTTP_X_REQUESTED_WITH"]) && ($_SERVER["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest")){
$token = $_POST["tok"];
echo $token ." - ". $sess_token;
} else {
echo "Not an AJAX request";
}
?>
What I get is the alert where one token is equal to the other and both are refreshed each time I reload the index.php file.
As a conclusion, your problem is not in the code you shared.
I have a Google App Engine PHP website. I have a page with the following recaptcha form:
<?php
ob_start();
if($_SERVER["REQUEST_METHOD"] === "POST")
{
//verify captcha
$recaptcha_secret = "6LfkBQMTAAAAABN5yEqoqxoLqKOBKIvoCHZ-3vP3";
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$recaptcha_secret."&response=".$_POST['g-recaptcha-response']);
$response = json_decode($response, true);
while (ob_get_status())
{
ob_end_clean();
}
if($response["success"] === true)
{
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=register.php">';
exit;
}
else
{
echo "Please try again";
}
}
?>
Once the user types in the correct recaptcha they are sent to 'register.php'. This all works fine and the user is sent correctly. But the problem is the user can just type 'register.php' into the URL and access it. I am trying to make it that the user can only access this page if the recaptcha has been entered. (The recaptcha is on a different page to 'register.php').
I am using sessions, when the user is logged in, so have this on register.php and this needs to stay there:
<?php
session_start();
if ( !isset($_SESSION['username']) )
{
header("Location:error.php");
exit();
}
?>
Is there a way to do something like:
<?php
session_start();
if ( !isset($_SESSION['username']) )
{
header("Location:error.php");
exit();
}
and ($response["success"] === false)
header("Location:error.php");
exit();
}
Seems like you're looking for the Or logical operator, save the value before the redirect:
if($response["success"] === true)
{
$_SESSION['success'] = true;
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=register.php">';
exit;
}
And now add a new check:
<?php
session_start();
if ( !isset($_SESSION['username']) || $_SESSION['success'] != true )
{
header("Location:error.php");
exit();
}
?>
If any of those expressions is true then the error block will be executed.
I have a problem with a file that involves session in PHP.
I have the following two php files:
confirm_save.php
<?php
include("confirm.php");
$_SESSION = array();
$token = $_SESSION['logout'];
if ($token && $_POST['token']==$token) {
if(isset($_COOKIE["id"]) && isset($_COOKIE["user"]) && isset($_COOKIE["pass"])) {
setcookie("id", '', strtotime( '-5 days' ), '/');
setcookie("user", '', strtotime( '-5 days' ), '/');
setcookie("pass", '', strtotime( '-5 days' ), '/');
}
// Destroy the session variables
session_destroy();
/*// Double check to see if their sessions exists
if(isset($_SESSION['username'])){
header("location: message.php?msg=Error:_Logout_Failed");
} else {
header("location: index.php");
exit();
}*/
header("location: index.php");
}
else {
// log potential CSRF attack.
}
unset($_SESSION["logout"]);
?>
Then, I have the confirm.php
<?php
session_start();
$token= md5(uniqid());
$_SESSION['logout'] = $token;
?>
<html>
<body>
<form method="post" action="confirm_save.php">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
Do you really want to log out?
<input type="submit" value=" Yes " />
<input type="button" value=" No " onclick="history.go(-1);" />
</form>
</body>
</html>
After clicking "yes" in confirm.php, I get the following error:
Undefined index: logout in C:\wamp\www\confirm_save.php on line 4
Line 4 is
$token = $_SESSION['logout'];
I really do not know what the error may be.
You empty your $_SESSION by
$_SESSION = array();
and then try to fill $token
$token = $_SESSION['logout'];
with no value.
There shouldn't be a reason to empty $_SESSION, nor to define $token as you include confirm.php which also includes your $token with value
EDIT
Don't include confirm.php
But do:
<?php
session_start();
$token = $_SESSION['logout'];
if ($_POST['token']==$token) {
...
On line 3 you set $_SESSION to an empty array, meaning that $_SESSION['logout'] doesn't exist;
$_SESSION = array();
$token = $_SESSION['logout'];
I can't see a reason why you would want to empty the array, so you can remove that line.
You don't need the second line anyway. $token will be available as set in confirm.php.
see: http://www.eat-drink-etc.com/
I have this code in the header of all the sites' pages:
<?php
session_start();
if (!isset($_SESSION['responsibility'])) {
//echo '{redirect="responsibility/message"}';
echo "<script type='text/javascript'>window.location = '{site_url}responsibility/message'</script>";
}?>
Redirecting to mydomain/responsibility/message if the user is a first time (or hasn't visited recently) visitor to the site.
In the message page I have the following:
<?php
session_start();
/*if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
$_SESSION = array();*/?>
function setcookielive($name, $value='', $expire=0, $path='', $domain='', $secure=false, $httponly=false) {
//set a cookie as usual, but ALSO add it to $_COOKIE so the current page load has access
$_COOKIE[$name] = $value;
return setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
}
if(isset($_POST['set'])) {
if(isset($_POST['remember'])) {
/*if(setcookielive("responsibility", "confirmed", time()+60*60*24*30*24, "/")) {
}*/
$_SESSION['responsibility'] = 'confirmed';
echo '{redirect="/"}';
}
else {
/*if(setcookielive("responsibility", "confirmed", time()+60*60*24, "/")) {
}*/
$_SESSION['responsibility'] = 'confirmed';
echo '{redirect="/"}';
}
}?>
The page uses a from input to enter the site:
<form method="post" action="">
<input type="hidden" name="set" value="set" />
<input type="hidden" name="remember" value="true" />
<input type="image" src="{site_url}images/elements/enter-btn.png" width="95" height="26" alt="Enter" value="Enter" />
</form>
Example: if a user goes to http://www.eat-drink-etc.com/articles/fi_europe_ni_2011
they will be redirected to the responsibility/message page. When enter is clicked the user is taken to the home page. (as specified)
How do I redirect to the originally targeted url??? eg. ../articles/fi_europe_ni_2011
Fisrtly, why are you performing the browser redirect through Javascript (client side) when you could do the same thing server side with a header("Location: $url;"); call?
<?php
ob_start();
session_start();
if (!isset($_SESSION['responsibility'])) {
ob_end_clean();
header("Location: $url; ");
exit;
}
// etc... you would need to call ob_end_flush(); before ending the page if you plan to have output here.
Something like that, to start with.
To answer your question: You would need to retrieve the current URL and store it as a session property before redirecting to the messages page. To amend my above example:
<?php
ob_start();
session_start();
$_SESSION['last_url'] = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
// etc
You could then access this URL on the confirmation page by again performing a header redirect like this:
header("Location: {$_SESSION['last_url']}");
You could do:
<?php
session_start();
if (!isset($_SESSION['responsibility'])) {
header("Location: /responsibility/message?refer=" . urlencode($_SERVER["REQUEST_URI"]));
}?>
And on your responsibility page you do something like:
if(isset($_POST['set'])) {
if(isset($_POST['remember'])) {
$_SESSION['responsibility'] = 'confirmed';
if( isset($_GET['refer']) )
header("Location: " . $_GET['refer']);
}
}
You might need to add a few checks to the $_GET['refer'] so that it won't get abused but you get the idea