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.
Related
i'm new to php, and i'm having a hard time establishing proper session mgmt. controls to prevent unauthorized access to a specific section of my site. I'll give an example...
myimaginarysite.com/application/index.php has a form to auth the user and it will redirect you to 'portal.php' after successful auth. 'portal.php' will check for a valid session as part of an include and then based on that it will either send u back to authenticate via header("location....) or just load up the HTML content. Now, if an unauthorized user hits 'portal.php' directly.. because they won't have a valid session.. they will get redirected back to the index, however, if you proxy the traffic you will see that the whole HTML content for 'portal.php' will actually be sent to the client (although not displayed on the browser) before redirecting back to the login page. So my question is... am I missing something, is there a way to make sure the HTML content is suppressed and is not sent to the client??
below is a snippet of my code for 'portal.php'
<?php
include "includes/checksession.php";
?>
<html>
<body>
Who Am I ??
<br></br>
Log Off
.....bunch of authenticated content.....
</body>
</html>
You need to stop script execution after sending the redirect headers with die() or exit(). Header redirection only sets the http headers, otherwise the page content is the same unless you instruct it otherwise.
Stopping script execution, like Juhana suggested, is probably the easiest solution for now, but there are other possibilities of course. You can just make the output conditional:
<?php
if (checkSession())
{
// redirect to login page
}
else
{
// output HTML.
}
If your site grows larger, it will probably (hopefully) also be more structured. If so, it might be easier to include other page fragments. So your code could look like this at first:
if (!checkSession())
{
include 'loginpage.php';
}
else
{
include 'portalpage.php';
}
And eventually maybe:
if (!checkSession())
{
ApplicationContext.setController(new LoginPageController());
}
Whatever the case, exit works fine and may be useful, especially for a case like this, but it terminates your script quite abrubtly, so it might get in the way of other processes that you may want to include, like debug-output or logging, profiling, and stuff like that.
I am in the process of building a website (via MODx), and I don't want "non-logged in" users to be able to see the home page, but instead be redirected to an "under construction" page.
In my snippet, this is what I have so far:
<?php
if (! $modx->user->hasSessionContext($modx->context->get('key')) ) {
$modx->sendRedirect('https://google.com');
} else {
return '';
}
Sadly, this appears to not do anything, regardless of whether or not the user is logged in. (It apppears to be a problem with the second line, the actual redirect worked fine when I tested it)
I am unable to figure out what is wrong, and any help is greatly appreciated!
The snippet that is in the page is [[!notloggedin]]
These are right out of Bob's guides, but basically what you want to do is check to see if the user has an ID or username, if not, they are not logged in.
You probably want to do a bit of digging and see if you can implement your redirect in a plugin rather than a snippet possibly an onRequest event - so you are not rendering the page/resource before you discover that the user needs to be redirected.
There are various methods. One easy method is to use this code:
if ($modx->user->get('username') == '(anonymous)') {
/* user is not logged in */
}
Here is the official method for seeing if the user is logged in to the current context:
if ($modx->user->hasSessionContext($modx->context->get('key'))) {
/* user is logged in */
}
If you know the name of the current context (e.g., web), you can use this method. The name of the context is required:
if $modx->user->isAuthenticated('web') {
/* user is logged in to web context */
}
If your site is simply not yet ready to be publicly available, MODX already allows for this.
See the following System Settings:
site_status
site_unavailable_message
site_unavailable_page
Alternatively, just set all your resources to 'unpublished', except for your custom error page. Logged in users will still be able to view all resources.
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 am looking for a way to serve cached redirects (via filesystem). So I would have a /cache/ folder with files like "google.txt" and using file_put_contents() insert 'http://www.google.com' into the 'google.txt' file.
The problem is that I want to actually track the ip's, views, etc.. in the database, but I want to redirect the user as quickly as possible. So I have created a simple flag function to be used. Here is some pseudocode to better illustrate:
if redirect_is_cached() //True if google.txt exists
redirect_to_link() //actual redirect header(location:...)
user_was_redirected_via_cache(TRUE) //STATIC: defaults to FALSE if no parameter is used.
//No exit because I want to track data but database isn't loaded.
...
code snipped out...later on in the script.
...
db_connect(); //Now we can access the database
if(user_was_redirected_via_cache()) { //TRUE since we flagged it earlier.
track_redirect();
exit();// Proper exit. We redirect user quickly,
// but continue script so we can track redirect.
}
else { continue with rest of script }
My questions are 1) does this follow "best practices" or is it kind of hackish? and 2) Does the user start getting redirected at the header() or the exit()? If the user doesn't start getting redirected until I actually exit() the script...this is kind of pointless.
Thanks for the help.
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;
?>