I have a web app where most of the functionality is within a javascript file, and I am about to introduce a pro version of the app in which registered users would get access to more functionality.
Again the extra functionalities are just extra functions in a javascript file.
What I am planning to do is:
- link pro_script.js if user is logged in,
- or link to normal_script.js if user is not logged in,
at the header of the page via user authentication with php.
I was wondering if this is the best way to approach this situation?
I have concerns that the pro_script.js is residing accessible under the javascripts folder, and it would be possible to write a script or plugin that loads the pro_script.js instead of normal_script.js.
You can have your HTML to call my_script.php instead of my_script.js. This PHP file would simply output your JS depending on the state if the user is logged on or not.
You can hide pro_script.js behind PHP script - it will check user's account and if user is "premium" then it outputs content of pro_script.js, otherwise - empty string. Don't forget to setup correct headers (content-type and caching)
This is acually #Adnan's idea, but my response was far to complex for a comment.
Your my_script.php should look something like this:
<?php
session_start();
header("Content-type: application/x-javascript";);
if (!empty($_SESSION['PRO_USER'])) {
echo file_get_contents("js/pro_script.js");
} else {
echo file_get_contents("js/normal_script.js");
}
exit;
?>
Related
Hey so I have create a login system to a website and I wish to have this login appear when I type in my address. When I have typed in details and logged in, I wish to be redirected to another PHP file, but with the same address.... this way, All I need to do is type in my address if I am allready logged in and I will go to the site which requires login.
I have made a transaction happen identifing if the session is created, if it is, it redirects me to another page, but also to another URL. I tried googleing it, but couldn't find anything exact and straight forward.
Currently:
Login page:
www.example.com
Member page:
www.example.com/members
What I wish for:
Login page:
www.example.com
Member page:
www.example.com
The program structure should look like this.
index.php
if (user is logged in)
display dashoard
else
display login page
Since you are using PHP, make use of session functions. Thus, URL rewriting is no longer necessary.
Update
Assuming if you have file structure in PHP like this:
- index.php
- login.php
+ template
- login.php
- dashboard.php
You can do the following structure in index.php file.
define('IN_FILE', true);
if (isset($_SESSION['user'])) {
require 'template/dashboard.php';
} else {
require 'template/login.php';
}
In template/dashboard.php
if (!defined('IN_FILE')) {
exit;
}
// Then your HTML, PHP and whatnot
And in login.php
if (!isset($_SESSION['user'])) {
require 'template/login.php';
} else {
header('Location: index.php');
}
Change the code according to your needs.
This can be achieved using several approaches.
a) Use session to determine the current page, so if a user click on a link, create a session store the value and on page load read the session data and include the file accordingly.
b) Use URL parameter to determine the page (this is the most common approach). for example in index.php you can add more parameters like index.php?page=somepage and by reading the value using $_GET and including the PHP file accordingly.
There are some more way to achieve what you want to, for instance using javascript/jQuery this is possible.
So I've got a Backbone application + web homepage. Right now, if you login to my website, I create a global object with your user details from the database. However, you can still just hit one of the routes in the application directly.
How should I handle users who are not "logged in" and redirect them to a "you must login page"?
Is this a standard operation? Basically, I have a REST url setup that returns just
{ sessionId: [php-session-id-here] }
If they are logged in, it would return something more like this:
{
sessionId: [php-sess-id],
userId: [user-id-from-db],
firstName: [f-name],
lastName: [l-name]
}
Ideas? Thanks!
What I've done in the past is to include on every page along with jQuery (actually, added to the jQuery file) an extension on the AJAX method to check for a custom code that I send when a user isn't logged in. When that value was seen it redirected the user to the login page regardless of what was going down.
This was because that site had a time out on login, so a user could get logged out while sitting on a page and then the AJAX request would just fail. If you don't have a timeout on the login the odds of ever seeing this issue are slim. Just ignore requests that come from users that aren't logged in.
If you need help coding this, start here: Extending Ajax: Prefilters, Converters, and Transports.
Really shouldn't require anything as complex as pseudo-code:
JS needs to do some AJAX, so JS talks to server
PHP checks for login if needed
If not logged in, send back the abort message (I used a converter to catch a "notLoggedIn" dataType. However this could also be done with a transport, they are just more complex.)
JS sees the abort message and does a window.location redirect rather than return AJAX message.
If you want, you could load a lightbox with a login form and send that via AJAX to PHP where a re-login can take place, if you remember the AJAX attempt that failed you can send it again after login. Then the user doesn't even need to leave the page to log back in.
If you're using jQuery, you can set a global ajaxSetting that allows you to do certain things upon certain http codes. Some pages I read recommend adding to your JSON a url field to point to where to login, but I figure that's just up to you. So the only modifications you'd need to implement what I've mentioned is 1. change the http code to something reasonable like 401 (unauthorized) and implement the http code handler. But I wouldn't call this standard, I'd just say that's what several people have done (including myself).
<?php
function IsLoggedIn()
{
if(isset($_SESSION['id'])) // Change that to what you want
{
return 1;
}
else
{
return 0;
}
}
?>
Then in your code, you could use something like:
if(isLogged()){ header('Location: http://google.com'); }
I have several pages inside an AJAX directory. I don't want these pages accessible directly so you cannot just type in the URL of the page within the AJAX directory and access it. I "solved" this by using a PHP session on the page that calls it as follows:
Main page:
<?php
session_start();
$_SESSION['download']='ok';
?>
and on the ajax page I have this:
<?php
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;}
?>
The only problem is that if a user goes through the correct process once, the cookie is stored and they can now access the page directly. How do I kill the session once they leave the parent page?
thx
why use session ?
if i understood what you want:
<?php /// Is ajax request var ?
if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH'])=="xmlhttprequest") {
// do your ajax code
} else {
// redirect user to index.php since we do not allow direct script access, unless its ajax called
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit();
}
} ?>
A really simple solution is to open up each of the files you want to protect from direct URL entry & add the following to the top:
<?php if (isset($_GET['ajax']) != true) die();?>
Now get rid of your redirect script since it's useless now. You don't need to use sessions for this. Every time you request a page, use it's direct URL, just add ?ajax=1 to the end of it.
By adding the ?ajax=1, PHP will set a key of 'ajax' to the $_GET global variable with the value of 1. If ?ajax=1 is omitted from the URL then PHP will not set a key of 'ajax' in $_GET and thus when you check if it's set with isset() it will return false, thus the script will die and not output anything. Essentially the page will only output data if ?ajax=1 is at the end of the URL.
Someone could still "spoof" the URL and add '?ajax=1' themselves, but that is not the default behavior for people or web browsers. If you absolutely need to prevent this then it will be much more complicated, e.g. using templates outside of a publicly available folder. Most other "simple" solutions will have the same "spoofing" potential.
There's really no way to accomplish this with a 100% certainty - the problem is, both AJAX and regular web browser calls to your web site are using the same underlying protocol: HTTP. If the integrity and security of your site depends on keeping HTTP clients from requesting a specific URL then your design is wrong.
so how do you prevent people from directly accessing files inside certain directories while still letting the site use them??
Create a controller file. Send all AJAX requests to this controller.
ajax-control.php
<?php
$is_ajax = true;
include "ajaxincludes/test.php";
// ... use the ajax classes/functions ...
ajaxincludes/test.php
<?php
if (!isset($is_ajax) || !$is_ajax)) {
exit("Hey you're not AJAX!");
}
// ... continue with internal ajax logic ...
If clients try to access the file directly at http://mysite/ajaxincludes/test.php they'll get the error message. Accessing http://mysite/ajax-control.php will include the desired file.
I don't think there is a surefire way to do what you are asking, since HTTP request headers can be faked. However, you can use $_SERVER['HTTP_REFERER'] to see if the request appears to be coming from another page on your site.
If the rest of the security on your site is good, the failure of this method would not grant the user access to anything they were not already able to access.
I've never tried this but maybe you could do something with jQuery's .unload() and then call a PHP page to unset() the session.
Why not (on Ajax page):
session_start();
if($_SESSION['download']!=='ok'){
$redirect='/index.php'; //URL of the page where you want to redirect.
header("Location: $redirect");
exit;
}
// do whatever you want with "access granted" user
// remove the download flag for this session
unset($_SESSION["download"]);
I am protecting my pages by checking the values of my sessions. Is there a more secure way of protecting my pages other than changing the Header Location if the sessions are not valid??? Am I doing anything right???
I have the following at the top of each page:
<?php
session_start();
//VERIFY LOGIN
$validkey = 'br1ll1ant)=&';
if ($_SESSION['valid'] != (hash('sha256',$validkey)) && $_SESSION['tokenconfirm'] != hash('sha256',$_SESSION['tokenID'])) {
header("location:/login/");
};
?>
using header() is fine, but don't forget to exit(); your script after calling header(). User agents don't have to respect headers, so one could write a client which will simply read the part that comes after the header call.
if(!session_is_valid()) {
header('Location: index.php');
exit;
}
Are you using a templating system? If you are, what you'd do is simply output the login form instead of the page content if the user isnt validated. Even if you arent using one, you can change the output (different set of includes, for example), if the user isnt valid. This way you arent relying upon the end user's browser to protect the content.
Headers should be fine, I haven't seen people use much anything else.
It is always best to authenticate to gain access to the page, and then check that authentication on every page. If it fails, redirect to the login.
Using a MVC pattern, it is best to check the login status before they even get to a page, and either redirect if not logged in, or load the logged in view.
Using a front controller pattern you can put all your php files outside the web root. That way they are not directly accessible from a URL. This is fairly common practice in PHP frameworks include those built with Zend 'Framework'.
If your files are in the web root, another method that you might consider is to use constants. This is how CodeIgniter does it. Define a constant in your front controller and if its not defined send them to the web root. Here is how to CI uses constants.
The constant used everywhere
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
How it is defined.
define('BASEPATH', $system_folder.'/');
$system_folder being a few lines above.
$system_folder = realpath(dirname(__FILE__)).'/'.$system_folder;
in php i used to authenticate whether a user was logged in or not by checking the session for a member id, if set ok, else the page would be redirected via Header to the login page. this auth script was in auth.php and i used to include it in any page that required login. simple. however i cannot do the same in jsp. because the rest of the page which includes the auth.jsp gets loaded no matter what auth.jsp does. the auth.jsp is
<%
UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();
if (user == null) {
%>
<jsp:forward page="/index"/>
<%
return;
}
%>
if the user is not logged in he still can see the original page below the login page. because of this i have to manually include the user checking using if else on every page, very inconvenient. any solutions??
the including page is
<jsp:include page="auth.jsp" />
<p>Welcome</p>
At the very least, you could write your own custom Servlet Filter. It gets called each time a request is made, without you having to do anything.
Also, you may want to look into something like Container level security, or evenSpring Security. Both handle this for you.
EDIT:
No problem.
In the mean time, you probably want to do something like this in auth.jsp
<%
if (user == null){
response.sendRedirect(redirectURL);
}
%>
which is sort of like
response.addHeader("location", "/login.jsp");
which is sort of like what you're used to with PHP.
A servlet filter is definitely what you're looking for. You can also grab container managed or spring security, but given your knowledge, those shall probably be some steps too far away to get a proper grasp.
Here's a basic example how the doFilter() method of your filter should look like:
if (UserServiceFactory.getUserService().getCurrentUser() != null) {
chain.doFilter(request, response); // User is logged in, just continue request.
} else {
((HttpServletResponse) response).sendRedirect("/login.jsp"); // Not logged in, show login page. You can eventually show the error page instead.
}
Map this filter in web.xml on an url-pattern covering the pages you'd like to authenticate. E.g. /secured/*, /private/*, /authenticated/* etc, and place all JSPs (expect of the login page!) in the same folder.
As to why it fails in a JSP: that may happen when the response is already committed. If you have read the server logs, you should have seen IllegalStateException: Response already committed at the point <jsp:forward> is been called. That is works in PHP is probably because it has a larger response buffer or because that logic is by coincidence correctly called before any part of the response body, thus right before <!DOCTYPE> and so on. As long as the response is not committed, you can change its destination using forward or redirect.