I have a problem with getting Joomla 3 to redirect users to a member page when a 403 is detected.
Upon researching and trying various things for literally days now I've finally given in to having to ask the question.
From my research I understand that the Joomla reads from the templates/system/error.php master file.
I have the following code implemented within the error.php and I have tried forcing it through .htaccess as well and neither work.
$ReferTo = $_SERVER['REQUEST_URI'];
$ReferTo = base64_encode($ReferTo);
if ($this->error->getCode() == '403') {
header('Location: ' . $this->baseurl . '/members'); die();
}
The current behaviour is Joomla just sends the user to a very unhelpful 403 default page.
Any ideas on this one? Thanks so much for any help.
Fortunately I have managed to find a solution by fluke. I dropped the system folder error.php file into all the individual template folders to create a system override. So far Joomla has recognised this.
Create under the main directory of your Joomla website, a 403.html file with the following content:
<meta http-equiv="refresh" content="0; url=http://www.yourwebsite.com/members" />
In your .htaccess file, add the following code:
ErrorDocument 403 /403.html
If you only want to do that for certain requests, then redirect to a 403.php file in your .htaccess file (instead of redirecting to 403.html file), check the REQUEST URI to see if it is indeed coming from the members area, and then redirect back to the members page.
Joomla creates/raises a 403 event, when trying to access a protected article. So editing the file System / error.php or within the template itself did not work. Also the other solutions in .htaccess or httpd.conf using ErrorDocument did not work.
I also tried the code this-> error-> getCode () == '403', but it doesn't fire.
The only solution I found was to modify the HTML view for the articles to redirect to an article where I show a login and a personalized message.
The file to modify is components / com_content / views / article / view.html.php line 134 to 139
Joomla 3.9.20
The code to replace is the following:
// Check the view access to the article (the model has already computed the values).
if ($ item-> params-> get ('access-view') == false && ($ item-> params-> get ('show_noauth', '0') == '0'))
{
$ app-> enqueueMessage (JText :: _ ('JERROR_ALERTNOAUTHOR'), 'error');
$ app-> setHeader ('status', 403, true);
return;
}
For this
// Check the view access to the article (the model has already computed the values).
if ($item->params->get('access-view') == false && ($item->params->get('show_noauth', '0') == '0'))
{
header('Location:https://www.yourwebpage/withLoginandCustomMessage.php');
die();
}
This will only be shown to users trying to view articles that require registration or with other ACLs.
I am aware that we should not edit the files since in a Joomla update, these changes could be lost, but it was the only solution I found (neither modules or plugins covered this problem and apparently it is something that is brought from joomla 1.5).
Related
I have a PHP site (site A, CakePHP 2.3) with its own login system. Then I have another "site" (it's actually an html generated ebook with its own index.html) in the same server, but on a different folder, let's call it site B.
I'm trying to allow only users that have a valid session on site A (have logged in with valid credentials) to view that ebook (access that index.html file). The main idea behind this is to prevent users from directly sharing site B's URL.
This would be easy if I could check the user's session on Site A from Site B, I could just check the $_SESSION variable, but that's not possible.
What's the simplest way to accomplish this? While not preferably, it's okay if I have to edit that index.html file from site B to add any code that could help with this.
One way I thought about was to do some javascript redirect from site A to site B that includes a POST variable, if the variable doesn't exist, then nothing is shown. This would require adding some php on that index.html on site B but I'm not sure it's the best solution, I wonder if there's something better.
Also, I have 100s of these ebooks so if it's something I can apply massively it would be much better.
EDIT:
For clarification, both sites are in the same server and have same "domain". To open site B I use a symlink from site A. For example:
Site A URL: http://example.com
Site B URL: PHP Redirect from site A to '/symlink/to/siteB/location/') which in practicality takes user to http://example.com/symlink/to/siteB/location/
Create a proxy
I would use .htaccess to redirect any url pointing to pages in the book to a custom action in the CakePHP application.
This action checks for credentials and if OK then reads from disk the actual requested file and sends it to the browser. Do not redirect back or you will cause a redirect loop!
Of course you need to create a redirect that passes the original requested page as a parameter so you know what file to read.
Granted this is not supper efficient but it works. I had to solve the exact same issue in an old project.
Notes
Make sure your .htaccess rules only intercept/redirect HTML links or else you need to pay attention to setting up proper response headers for CSS or Image files.
Example of .htaccess
This needs to be in the ROOT folder of the book
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(.*html)$ http://[FULL_LINK_TO_CAKE_APP]/proxy/load/$1
</IfModule>
Example of the proxy controller
namespace App\Controller;
/**
* Static content controller
*
* This controller will render a html file
*
*/
class ProxyController extends AppController
{
public function load($file=null){
if( !$file ){
return $this->response->body( "Error: no file specified" );
}
//THIS NEEDS TO RESOLVE THE FULL DISK PATH OF YOUR PROTECTED FILES
$pathToFiles = WWW_ROOT . '/subfolder/';
if( file_exists( $pathToFiles . $file )){
$this->response->body( file_get_contents( $pathToFiles.$file) );
return $this->response;
}
$this->response->body('Could not load the file: ' . $pathToFiles . $file);
return $this->response;
}
}
Security
Of course I assume you have setup the Auth component correctly in your AppController so the controller above will only execute if the user is logged in!
I'm designing a website but I know if the user enters a wrong character into my url, a not found page will open for him . and I know it can be a way to hack my website. What should I do for that? for example if the user enters a ' into my url like this:
http://example.com/article.php?id=585'
He move to a not found page which I have designed it or move to the first page or the last page he was in.
Thanks.
You have to take 2 things into consideration:
Handling non-existent files
Handling non-existent article ids
Here's how to handle each case:
1) Create an .htaccess file and place it in your website root folder:
RewriteEngine on
ErrorDocument 404 /error.php # change this to your own 404 file path
2) Open the articles.php file and add this to the top (right after checking if your ID exists)
if(!valid_id($id)) {
//if you have php 5.3- use this
header('HTTP/1.1 404 Not Found');
//if you have php 5.4+ use this
//http_response_code(404);
include('error.php'); //change this path to your own 404 file
die();
}
Obviously, valid_id() is just a function example.
You will have to create a custom 404 page. So when your website doesn't get that page, it will show your custom page.
Try this link for custom page.
By the way from id=585'(apostophe after 585), I mean you want to prevent sql injection. Right? Just sanitise the input, that is, check if id is valid for not. You can find a lot of tutorial for that, just google it.
P.S : Believe me, It would take a lot more then a 404 Page to hack your server
just use this:
Open the articles.php file and add this to the top (right after checking if your ID exists)
if(!valid_id($id)) {
header('location:error.php'); exit();//change this path to your own 404 file
}
valid_id() is just a checking function example.
I manage to disable the homepage on Prestashop.
I want that users arrive in a specific category and not on the homepage.
I've tried to do it in the htaccess file with a redirection of index.php to index.php?category_id=1.
It works but it generate the error Technical error unable to load form when the user try to create an account.
This applies to PrestaShop 1.5
You may edit controllers/front/IndexController.php file, which is responsible for the homepage, adding Tools::redirect call to whatever controller you want (this example is to cart).
public function initContent()
{
parent::initContent();
Tools::redirect('index.php?controller=cart'.($_REQUEST ? '&'.http_build_query($_REQUEST, '', '&') : ''), __PS_BASE_URI__, null, 'HTTP/1.1 301 Moved Permanently');
$this->context->smarty->assign('HOOK_HOME', Hook::exec('displayHome'));
$this->setTemplate(_PS_THEME_DIR_.'index.tpl');
}
Well for one way you can simply add a redirect to your index.php file, but that I guess is already evaluated and rejected solution:
header('index.php?category_id=1');
exit;
Another way of doing this might be using the prestashops modules, for example there is a module "homefeatured" which displays exactly the products for the home category and you can hook it on home position through Modules -> Positions.
If you would mind telling me the exact major version of prestashop you are using maybe I could tell something more.
We have a website based on Joomla! in the joomla directory, there are many other directories, i.e.:
C:\myjoomlawebsite
...joomla directories...
\myspecialdirectory
in "myspecialdirectory" there are resources that sometimes are available and other times are not available, as one would imagine, when a resource(php page) is not available, a 404 page is displayed.
What I would like to do is, "somehow" tell joomla that when the user tries to access a page located in "myspecialdirectory" and it's unavailable, it should show an article page rather than a 404.
if the user accesses mydomain.com/ <- all good
if the user accesses mydomain.com/existingpage.php <- all good
if the user accesses mydomain.com/unavailablepage.php <- a 404 should be shown
if the user accesses mydomain.com/myspecialdirectory/existingpage.php <- all good
if the user accesses mydomain.com/myspecialdirectory/unavilablepage.php <- here's where I want the user to see a article page in stead of a 404
Check this
For v1.5
if (($this->error->code) == '404') {
header('Location: /index.php?option=com_content&view=article&id=75');
exit;
}
For 1.6 & 1.7
if (($this->error->getCode()) == '404') {
Because that directory is outside of the Joomla framework, and you only want one directory to redirect to a Joomla page instead of a 404, then the easiest way to accomplish this is to use put a custom htaccess in the directory you want to redirect. You would want to add this to htaccess only in myspecialdirectory
ErrorDocument 404 /URL TO JOOMLA ARTICLE.php
For the standards-compliant solutions -- take a read here: http://magazine.joomla.org/component/k2/item/230
Typical scenario:
DB items are displaied in page http://...?item_id=467
User one day deletes
the item
Google or a user
attempts to access http://...?item_id=467
PHP diggs into DB and sees items does not exist anymore, so now PHP must tell
Google/user that item is not existing via a 404 header and page.
According to this answer I undertstood there is no way to redirect to 404 Apache page via PHP unless sending in code the 404 header + reading and sending down to client all the contents of your default 404 page.
The probelm: I already have an Apache parsed custom 404.shtml page, so obvioulsy I would like to simply use that page.
But if i read an shtml page via PHP it won't be parsed by Apache anymore.
So what do you suggest me to do?
Is there maybe some trick I could use palying with htaccess too?
Thanks,
Hmm. Two ideas come to mind:
Redirect to the 404 page using header("Location:...") - this is not standards-compliant behaviour though. I would use that only as a last straw
Fetch and output the Apache-parsed SHTML file using file_get_contents("http://mydomain.com/404.shtml"); - also not really optimal because a request is made to the web server but, I think, acceptable in most cases.
I doubt there is anything you can do in .htaccess because the PHP script runs after any rewrite rules have already been parsed.
IF you are using apache mod_php, use virtual('/404.shtml'); to display the parsed shtml page to your user.
I was trying to do this exact same thing yesterday.
Does Pekka's file_get_contents/include result in a 404 status header being sent? Perhaps you need to do this before including the custom error page?
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
You can test using this Firefox extension.
I was looking exactly for something like you needed, so you have a page:
http://example.com/page?item_id=456
and if later you want that if item is missing you are redirected to:
http://example.com/page_not_found?item_id=456
In reality I found it is much more maintainable solution to just use the original page as 404 page.
<?php
$item = findItem( $_GET['item_id']);
if($item === false){
//show 404 page sending correct header and then include 404 message
header( $_ENV['SERVER_PROTOCOL'].' 404 Not Found', true );
// you can still use $_GET['item_id'] to customize error message
// "maybe you were looking for XXX item"
include('somepath/missingpage.php');
return;
}
//continue as usual with normal page
?>
So if item is no longer in the DB, the 404 page is showed but you can provide custom items in replace or error messages.