In my website I set some values to session object like "user_status", "user_name" and like so. The php file looks like this:
<script type="text/javascript">
var logged = <? echo $this->session->getValueOf("user_status"); ?>;
</script>
<a class="show_message" href="#">SHow my status</a>
Well, I have a js script that pretends do an action according to user status in the website, so, I have this:
$('.show_status').click(function(event){
//ask for user status
if (logged){
//do something
}
else{
//do another action for visitors
}
});
Walking around I thought if it is the best way flow data between session -> javascript, because if you inspect the page source at browser the value of user_status will be visible and could be riskable for website security.
Thanks in advance
EDIT:
logged var only takes a boolean value.
The js action must be executed each time the element #(".show_status") is clicked.
If the JavaScript is just being used for interface stuff, and doesn't have any back end effects, I probably wouldn't worry too much about the insecurity of handling that logic client-side.
If security is an important thing though, I would recommend you use PHP to write the appropriate JavaScript function. For example:
On the page being viewed, perhaps in the header, you have:
<script type="text/javascript">
<?php
if ($this->session->getValueOf("user_status")) {
require_once('logged_in_user_functions.js');
} else {
require_once('visitor_functions.js');
}
?>
</script>
In the file `logged_in_user_functions.js' you have:
function showComment(id) {
//logic that shows the comment here
}
function showCommentSubmissionForm() {
//logic that adds this form to the page goes here
}
Meanwhile, in the file `visitor_functions.js' you have:
function showComment(id) {
//logic that shows the comment in a different way goes here
}
function showCommentSubmissionForm() {
//logic to display a message saying the user needs to log in to post a comment goes here
}
Then you can add your logic into your page without having to check the user status. The proper behaviour is provided by virtue of which .js file was included:
<button id='add_comment_button' onclick='showCommentSubmissionForm()'>Add Comment</button>
This gives PHP (and thus the server, not the client) final say in what gets displayed to the user.
Assuming that user_status will be something like Active, then this isn't really a security risk.
If you want to hide everything from casualy prying eyes, you could try using an encrypted cookie, using something like How to save encrypted data in cookie (using php)? to encrypt your values.
Related
I have a login area of my site, and on login I set a session variable $_SESSION['logged_in'] = true.
Now I also have lots of forms and things where users can input comments. Obviously in my PHP validation I check the user is logged in simply using the session variable, but I want javascript validation too because I can make the user experience slicker that way.
$("body").on("click", ".submit", function(e){
e.preventDefault();
if (user == logged in){
...AJAX call to php file....
}
})
So how do people generally do the bit where I check the user is logged in using javascript?
ie
if user == logged in
You can of course check user permissions by AJAX (with JSON for example), but this will provide some additional latency.
You can just write a value to global JS scope like this:
if ( userIsLogged() ) {
echo "<script>document.mysite.userlogged = true;</script>";
}
then you can check document.mysite.userlogged variable.
You can also set a cookie in PHP, wich can be obtained in JavaScript. To get cookies properly in JS see that: Javascript getCookie functions
If you don't want to inject JS code, you can set some attribute like:
<div id="comments" data-logged="<?php echo $isLogged; ?>">
...
</div>
And get it by jQuery:
if ( $("#comments").attr('data-logged') == 1 ) {
you can provide logged/notlogged specific functionality for the whole page by generating JS file, like: <script type="text/javascript" src="http://yoursite.com/somefile.php"> and generate it in php dynamically, but be aware of caching !
Personally i would go to data-XXX attribute if tou want to personalize single block, and global JS variable if you check logged condition many times in JS.
I want to show different div with different contents in different condition.
If customer is logged in, then show content A,
If customer is not logged in, then show content B,
This is the script I have, not sure it is correct or not.
<?php if (!$logged) {
$disp_div=1;
} else {
$disp_div=0;
} ?>
This is the jQuery
<script type="text/javascript" >
$(document).ready(function(){
var show=<?php echo $disp_div; ?>
if(show==1)
{
$('#div_logged_in').show();
$('#div_not_logged_in').hide();
}
else if(show==0)
{
$('#div_logged_in').hide();
$('#div_not_logged_in').show();
}
});
This is the HTML
<div id="div_logged_in">
Content A
</div>
<div id="div_not_logged_in">
Content B
</div>
A: Why !$logged is wrong:
You use a local variable. Next time your user refreshes the page he won't be logged in anymore. For that you can store variables in a array called $_SESSION . This array is saved for a client session on you webserver. As longs as the user stays there it will always remain the same (until YOU change it). For that you need a session_start(); in the first line of you main PHP script.
B: Why the javascript part is a security leak:
Your website is designed not to filter the content that is sended to the user. Every user gets the whole content, just the visibility is changed. In this way every advanced user can just look into your code and see all the secrets you want to hide.
C: What is the right way?
It just some PHP that echos HTML without Javascript and uses $_SESSION:
<?php
if($_SESSION["loggedIn"] == "yes") { //You have to set that somewhere else just like $logged
?>
<p> You ARE logged in. </p>
<?php } else { ?>
<p> You ARE NOT logged in. </p>
<?php
}
?>
I don't know what is $logged. If it is the variable to find whether the user is logged in, then your condition is just opposite of your requirement. You are showing div_logged_in when the user is not logged in from this condition.
if(show==1)
{
$('#div_logged_in').show();
$('#div_not_logged_in').hide();
}
The value of show will be 1 when $logged is false. So change the condition and you will get it. In this scenario, i would suggest you to go with SESSIONS. You can use anywhere to check whether the user is logged in or not.
First off, you need to start reading about sessions and the $_SESSION superglobal.
After that, throw that script away, and look for a proper tutorial, I found a very nice one here: http://net.tutsplus.com/tutorials/php/a-better-login-system/ - though it may be a bit advanced since it talks about ACL, which you probably won't need.
But if you can try and understand the rest of the tutorial, you should be fine. Good luck!
Please do not depend on client-side validation because its a security flow within your application, what if the customer viewed the source code for your page? then they see hidden contents.
Your approach is correct but you have to use $_SESSION or $_COOKIE not if (!$logged) and as I said, do not out put the content totally.
use
if($_SESSION["username"])
you can set it in the login.php file
and destroy it by using session_destroy() on the logout.php
My goal is to set a Google Conversion value from a custom field defined in WordPress. The conversion script is located on the landing page, so I need to get my custom field data from my form to the landing page. I can't use GET or POST as the form submission is handled by a third party and no data is returned to the actual landing page.
So I've tried using a PHP session, but this third party is getting in the way of just being able to use PHP, because it's keeping all the data for itself.
This is the approach I'm hoping I can get working:
The validation for the form is done using jQuery Tools.
I then need to submit the variable after validation has been successful via jQuery/AJAX to a separate php file.
Then as the landing page starts to load, I must grab that variable from mentioned PHP file and echo it in the relevant place.
I figured I don't actually need to start a session on the page with the form, as jquery is grabbing the data straight out the input, not any session data. So here's my input with conversion value:
<input type="hidden" id="conv" name="conv" value="90">
Then my form validation:
$("#course-form-modal").validator().submit(function(e) {
// when data is valid
if (!e.isDefaultPrevented()) {
// this grabs the value from my form
var con_val = $("#conv").val();
// and this sends it...
$.post(
"../../usersession.php",
{ data: con_val }
);
}
});
Then I've got the code in usersession.php... where I sent the data:
// As I'm just trying to echo what was sent to this page, via ajax, I shouldn't need to worry about starting/retrieving a SESSION yet... right?
<?php $var_value = $_POST['data']; ?>
<div id="results">
<?php echo $var_value ?>
</div>
// I CAN WORRY ABOUT THIS HALF LATER. RIGHT NOW I JUST WANT TO ECHO MY RESULTS ON USERSESSION.PHP //
Finally, I've got the code on my landing page to retrieve the data from usersession.php:
session_start();
$var_value = $_SESSION['conv'];
echo $var_value;
I'm not entirely sure all this code is right for starters, I'm more of a front end guy...
-EDIT-
Right, I'm pretty sure the code is correct at least now. For some reason it's still not working though. At the moment I'm wondering if WordPress would prevent me writing to usersessions.php from my javascript file (for reference, that file path is set absolutely in my working (not working) example)? I know WordPress will sometimes throw a 404 when you try to access a file directly.
The other potential issue could be with the third party software, vanillasoft. I've a link to their script in the action tag of my form, could that somehow bypass/kill the sending/receiving of data between the form > usersession.php > and then the landing page?
On a side note, if anyone has a great idea on how I can test if usersession.php is receiving the data then please let me know? I did have this code originally, but it returns nothing and if I link straight to the file after a send something (as in just paste the file url in to my browser) it returns a '0'...
if(isset($_POST['conv'])) {
session_start();
$_SESSION['conv'] = $_POST[''conv''];
echo "1";
} else {
echo "0";
}
Set your ID on the input. jQuery is looking for the ID, but you have only set the name.
<input type="hidden" name="conv" value="90">
Should be:
<input type="hidden" name="conv" id="conv" value="90">
EDIT:
Can't believe I didn't catch this earlier. Your problem is in the usersession.php at the following line.
$_SESSION['conv'] = $_POST[''conv''];
You have the POST quoted wrong.
It should be:
$_SESSION['conv'] = $_POST['conv'];
EDIT (re: New js edits)
In you java script your post vars should be formatted thusly:
{ name: "John", time: "2pm" }
So your line should be something like this:
$.post(
'../../usersession.php',
{
conv: $("#conv").val()
},
function(data)
{
alert("Data Loaded: " + $("#conv").val());
}
);
I tried to understand - is it any method to ask browser not to refresh entire page when user clicks onto . Hash adding method is seen - I need another method, working with links without hashes.
May be any headers should be sent ? Or something another ?
I want to process GET queries returning only the part of HTML (or special js commands), not all page, and process it in AJAX-style.
You can ajaxify your links through jquery. Something like this:
$('a.ajax').click(function(ev){
ev.preventDefault();
var target=$(this).attr('data-target');
var url=$(this).attr('href');
$(target).load(url+' '+target);
}
This can be used in conduction with the following HTML:
<div id="output">
Hello World
<div>
and inside world.html you would need to have:
<div id="output">
Foo bar baz boo
</div>
In theory this should load content of the dif from "world" file into the div inside the first file, but I haven't tried it. I think it's what you need, because the regular link is still there, google will properly index this bypassing ajax and your users will be happy to see part of the page change.
you could make it 'fake' links doing something like this:
<span style="cursor:pointer;" onclick="loadPage('mypagename');">My Link</span>
The function then would be:
function loadPage(pageName){
// do ajax call here using pageName var
}
You cannot prevent navigation when a user clicks a hyperlink with a URL. Using a hash value to navigate or having your hyperlinks invoke JavaScript is generally the way to add navigation inside of a single page.
However, if you're trying to convert an existing page that's not designed this way, you would have to use JavaScript to modify hyperlinks so they invoke Ajax. For example:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
var oldUrl = links[i].getAttribute('href');
links[i].setAttribute('href', 'javascript:void(0)');
links[i].onclick = (function(url) {
return function() {
// Then you can do your AJAX code here
}
})(oldUrl);
}
I recommend that you don't do something like this, though, and rather create your page with an AJAX design in mind.
Changing the url without using hashes can be achieved with the Html5 History API: http://html5demos.com/history
Not supported by older browser though, so you must always have a fallback.
I know how to get an AJAX response:
$.post( '/action',
{ actiontodo: 'insert' }
function (data) { alert(data); } );
Int the action.php (server side):
<?php
if ($_POST['actiontodo'] == 'insert')
{
doInsertAction();
echo "inserted";
}
?>
Finally the output of this code is an alert BOX with the word: inserted.
BUT, without ajax, I have two ways to solve this (in the server side):
ONE:
<?php
if ($_POST['actiontodo'] == 'insert') {
doInsertAction();
header( "Location: " . $_SERVER['HTTP_REFERER'] . " &response=inserted" );
} ?>
TWO:
<?php
session_start();
if ($_POST['actiontodo'] == 'insert') {
doInsertAction();
$_SESSION['response'] = 'inserted';
}
header( "Location: " . $_SERVER['HTTP_REFERER'] );
?>
Returning to the page I get the answer from the SESSION or from GET and shows the alert.
I like more the ONE solution, but each solution has a problem:
ONE problem:
The returning URL is : http://www.foo.com/myrefererurl&response=inserted
If you types this URL without using the form, you will see the alert BOX each time you will refresh the page. The question is: How to show the message only ONE time? (ONLY AFTER THE FORM ACTION)
TWO problem:
The SESSION now has the value inserted ($_SESSION['response']), when the page returns from the action obviously the solution maybe delete this value of the session like: unset( $_SESSION['response'], but SUPPOSE the UNSET do not reached for any reason (connection failure or navigation stopped by the user, etc), when you go to another form in other page the alert will showed because the $_SESSION['response'] still exists (in another form without submit it and has nothing to do with that response). Inclusively WITH GET &response=inserted in another URL the problem will exists too.
I hope you understand this questions and bring a BEST WAY solution. Basically the question is how to control that responses......
Unobtrusive JS, or "progressive enhancement" is the way to go.
Step 1:
Build your page first to work without JavaScript. Let's say you have a simple application where a user selects something and hits submit. Depending on the selection, you will either display a helpful error message above the form or you'll update the page with the correct output and hide (or get rid of) the form. Build this page like you would for AJAX, but do not script anything yet.
Here's your page:
<html>
<head>
<style type="text/css">
p#feedback { display:none;}
</style>
</head>
<body>
<div id="feedback"></div>
<div id="form">
<form action="getaction.php" method="post" id="actionform">
<select name="requestedAction">
<option value="foo">Do Foo</option>
<option value="bar">Do Bar</option>
</select>
<input type="submit">
</form>
</div>
</body>
</html>
On a successful submission. the server will get a request with one $_POST value: requestedAction=foo (or bar). Based on this, your server script will construct a new page with everything from <html> to </html>.
At this point, you have a page that works in any non-JS-enabled browser. Old fashioned. Very reliable.
Step 2
Add the scripting to override the default submit behavior. Grab the data you need from the page and construct an AJAX submission. The only difference between this and the submission above is that you will add a flag telling the server that the request is coming via AJAX and to send back only the needed message (you could also send it to a different script). The server script will basically go through the same logic as above, but rather than building the entire page, it only sends back the message string and leaves it to AJAX to put that data in the right place. Your response could be just a text fragment, a block of HTML or an XML data structure. It depends on your needs.
<script type="text/javascript">
$(enhance); // at onDOMReady, run the enhance function
function enhance() {
// Override the default form submission behavior:
$('form#actionform').bind('submit',doSubmit);
};
function doSubmit(event) {
$.ajax(
{
type:'POST',
url:'/path/to/getaction.php',
data:'request=' + $('form#actionform select[name=requestedAction]').val() + '&type=ajax',
success:fnCallback
}
);
// Kill the submit action so the user doesn't leave the page
event.preventDefault();
};
function fnCallback(xhr) {
var strResponse = xhr.responseText;
if (strResponse === "error") {
$('div#feedback').text("There was an error. Please try again.");
}
else {
$('div#feedback').text(strResponse);
$('div#form').hide();
}
};
</script>
In this case, the AJAX submission will be identifiable to the server because there is a second POST parameter of type=ajax.
A site that does this really unbelievably well on a very big scale is ESPN. Turn off JS and check out their main story headlines under the big picture. The behavior is identical to their AJAX-enabled page and aside from the video not working, you really would never know if your JS was on or off. There's basically no way to build a site like this without starting from dumb HTML and building up.