I want to create a function that will check if the user is logged in. If so, the user should be navigated to userActive, otherwise the loginForm should be displayed.
I also want to carry out a check on the loginForm page to check if the user is logged in. If so, they should be taken to userActive, or kept on the loginForm page.
Why issue is why the following code doesn't work. I keep hitting a loop.
$_COOKIE['user_id'] = "user_id: 1";
activeUser();
function activeUser()
{
if($_COOKIE['user_id'] == "user_id: 1")
{
header('location: index.php?a=activeUser');
}
else
{
header('location: index.php?a=loginForm');
}
}
switch($_GET['a'])
{
case 'loginForm':
include_once('loginForm.php');
break;
case 'activeUser':
include_once('activeUser.php');
break;
}
That is not the proper way to set cookies in PHP. See the documentation for details.
If you are putting this on your index page... you are redirecting to your index page with a GET variable.... so... loop after loop to the same page.
You are not setting cookies properly as well.
You may want to research SESSION variables as well as that may be easier to grasp when implementing a login system.
This is how most frameworks do it :
Redirect all of the request to a single page : index.php
In this file load all the functions/classes you need (bootstrap), this could be :
Is the user logged in (restricted access)?
what country is he from (show content near him) ?
what language does he speak (site in english or spanish...) ?
...
finally : where does he want to go (the page), can he go there? if not redirect.
Building all of this from scratch could be tricky, sessions, cookies, redirects, layouts, views, 404, 500, databse queries (safe ones)...
Most people use frameworks, here is a list of some of them :
CakePHP
CodeIgniter
Symfony
Zend Framework
Hope it helps.
Related
I have a framework and I think I'm following something like the MVC pattern: A framework (the model) an index page that controls the input (the controller) and the views pages (that are included inside main.php/the main html)
I read a lot about structure and logics, to write a good application. I read many comments like "Why are you outputting anything if all you are going to do is try and redirect the user to another page?". Well the answer is, the most common case: redirect after the user successfully logged in. Do I need to print something? Of course, the whole main page with a login form/post. How I'm supposed to do that redirection??
So I'm a bit confused about logics and structure of the application. How do you store all the output and do the header redirection without printing anything?
I was thinking about using javascript to do the redirection but I also read comments saying; "if you write good code (following a good logic/structre), you won't need to use hacks like javascript redirection". How is that even possible?
Because the php output_buffering should not be enabled.
I have the output_buffering enabled, and I can use header (after output) without any problem. If I use the javascript redirection the whole page reloads, but using header it just loads the content (the views content that are included in main.php).
So how do you do this without output_buffering?
If you want to redirect to a success page AND pass messages - say, after a successful login - an easy solution is to use "flash" sessions, where you store a message in a SESSION and then, as soon as it's used, you discard it. You don't need to sore anything in the output buffer for this.
This is a very basic example, but should give you the gist of it.
login.php
if($login_successful) {
// put your message in the session
$_SESSION['message'] = 'Login Successful';
// redirect to the success page
header('location: success.php');
}
success.php
<?php
session_start();
// check if $_SESSION['message'] exists
if(isset($_SESSION['message'])) {
// print the message
echo $_SESSION['message'];
// clear the session
$_SESSION['message'] = null;
}
Looks like you are mixing up some things here. What you are talking about are actually two different requests. Either the user wants to view the main page, or he wants to log in using that form on your main page. In your index.php you would have something like this (pseudocode):
if (isLoginRequest) {
// user wants to log in
if( validateLogin($loginFormData) ) {
redirect('successful');
} else {
displayLoginError();
}
} else {
// user wants to view main page
echo main.html
}
Update to answer the question in the comments: The better alternative would be to leave your form validation stuff in login.php and refer to that in your login form <form action="login.php" .... Then in your login.php you would have something like this:
if (loginSuccessful) {
redirect('success.php');
// no need to call die() or whatever
} else {
setFlashMessage('Login failed'); // set a flash message like timgavin described
redirect('index.php')
// also no die() or whatever
}
index.php then is responsible to display your main page and, if set, rendering the flash message from a failed login attempt.
Simple solution: Move the login post script from login.php to another file (login_post.php). The same for other scripts using header() after dom output. (no need to change the form action="")
In index.php:
$url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
//some more security checks like esc_url() (non-php function)
if ($url == '/login') {
include('header_pages/login_post.php');
}
// all these includes before including main.php
// where views pages are included and the DOM output starts
Since header() is inside the post script, no more headers already sent errors (And output_buffering off, of course).
Same for logout page that is currently being included inside main.php
Thanks to the other answers, they helped me finding this solution.
I have index.php that include pages like
<?php
define('MyConst', TRUE);
include_once('template/header.php');
if (!empty($_GET['action'])) {
$action = $_GET['action'];
$action = basename($action);
include("template/$action.php");
} else {
include("template/main.php");
}
include_once('template/footer.php');
?>
With in a template directory I have main.php which has link to other pages like page1.php, page2.php.
Goto page 1
Goto page 2
How could I prevent users form accessing pages directly typing "http://mydomain.com/?action=page1" on the URL? And redirect them to main.php if they have done it?
You can not. What you want is simply not possible.
For the server side there is no way to know whether an URL is typed or clicked.
If I understand correctly, the thing you want is to prevent the user to access http://example.org/?action=page1 unless they came from http://example.org/?action=main. To do that, you must be able to detect whether they came from http://example.org/?action=main. The safest way to do that is to generate some random value that you associate to the users when they access http://example.org/?action=main and to check whether there is a correct value associated to the users when they want to access http://example.org/?action=page1. If not, they tried to access that page directly.
Check for HTTP_REFERER and if it is not pointing to right values (like your meny page) then redirect user.
Maybe you can try this, On your index.php :
session_start();
if(! isset($_GET['action']))
{
$_SESSION['pageAccess'] = true; # Set the key whatever you want
}
then under that script (we need that session_start() used twice) :
if(isset($_GET['action']))
{
if(! isset($_SESSION['pageAccess']) || ! $_SESSION['pageAccess'])
exit('There is no direct access allowed.');
}
Hope this help, have a nice day.
As per your Question:
There are two approaches that you can follow:
Use HTTP_REFFRER and check on desired page if User is coming from the page u wanted. IF he is accessing the direct URL then show him error page.
Use $_SESSION but this approach can be harmful as SESSION will always be there untill browser / instance closed.
So better to go for 1st approach.
And also as per Pehaa, you can not check id URL is typed
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.
I have the following PHP script within a file named login.php
<?php
$ref = $_SERVER['HTTP_REFERER'];
if ($ref == 'http://example.com/dir/invalid.php' || $ref == 'http://www.example.com /dir/invalid.php') {
echo '
<div id="invalid">
TESTTESTTESTTESTTESTTESTTESTTEST
</div>
';
}
?>
I have deliberately went to the invalid.php page (which redirects using header() to login.php) and this div does not show up. Does it have something to do with the referrer not really being invalid.php or is there an issue with the script?
Thanks
I don't think the HTTP_REFERER is what you think it is. Namely, it is the page from which the user followed a link to the current page. However, it's very unreliable as we rely on the browser of the user to correctly report this value.
I would suggest the option I thought you needed, except that the only one I can think of you might doesn't really makes sense... (checking if the url matches a url that's not the current script)... so I do not see what you are trying to do.
As promised several ways to do what you want to achieve:
First off, I don't like this solution at all and really consider it ugly, but it's the one closest to what you where trying to do.
invalid.php
require 'login.php'; // we include the file instead of referring to it
login.php
if ($_SERVER['SCRIPT_NAME'] == 'invalid.php')
{
// do whatever
}
The main difference between what you did and what I did for the user will be that here the url bar will show that you're at invalid.php and not somewhere else. This also means that refreshing doesn't make the message go away.
A better solution in my opinion is the following:
In your script that logs a user in (checks the database and everything):
if (!valid_login()) // pseudo-code, obviously
{
$_SESSION['invalid_login'] = true;
header('Location: login.php');
// previously, we had something like this instead of the two lines above:
// header('Location: invalid.php');
}
in login.php
if (isset($_SESSION['invalid_login']) && $_SESSION['invalid_login'])
{
$_SESSION['invalid_login'] = false;
// do whatever
}
Of course, this should be done with proper session facilities like starting up the session in both those files. Instead of using session variables, you could include the file and use normal variables or send GET variables through the header request, but both those solutions share a problem: refreshing doesn't make the message disappear. However, if you were to move the code from the top file of the two above to login.php (if it's not already there, I don't know what file that actually is...) you could once again use normal variables instead of session variables and have a solution in which refreshing does make it go away. In this case, you might argue that you are cluttering your files with bussiness logic and presentation, but there are solutions to that (like keeping it in a separate file, and including it into login.php, moving the html to another file and including that one into login.php or both.
I want the following:
After logging in, A user will have assigned session variable, and the logging in page will be refreshed. The URL should not be changed at all but the page would be different.
I don't know the idea of doing that.
I know that Facebook does it. (Logging in, and logged in page url is same but different page)
I'm using nginx, PHP.
Should I some sort of rewrite URL? or some configuration on nginx? Or should I manipulate header with php in some way? then how to?
just do a conditional on an include. In general if the session does not exist you say something like
<?
if (!isset($_SESSION['user'])){ include_once("login_please.php"); exit(); }
..actual page content
?>
Use PHP to decide what to show (or which page to include) based on the session variable.
if ($_SESSION['form_submitted'] == true) {
include('content.php');
}
else include('form.php');