I am building my first full API which I need for internal use in my business. Sadly, due to the nature of how I am going to utilize it, I have to have it on a public server. I am 6 hours in to parts of it being live and the log files show that there are already hundreds of access attemps in my log file. Considering that 6 hours ago the domain didn't even exist, it is astounding how many people are trying to access api.somedomain.tld/index.php /index.pl /index.html /index.py even. I want to curb it. So I want to setup that if someone types api.somedomain.tld/some/folder and that folder exists then I want to just serve the output of /index.php which just spits out a JSON data format with the string {"error":"Invalid API Endpoint"} Already I have it that if you type api.somedomain.tld/some/folder/ it automatically runs index.php in that folder. But that is a default. But I also want to set it up that if you try access any non-existing endpoint or file then I want to again, output /index.php All this without doing a 30x redirect. Currently I have /some/folder/endpoint and that effortlessly runs /some/folder/endpoint.php with out changing the URL. Anyone got some solid advice? Here is my current .htaccess in the webroot Code: RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /$1.php [L]
Okay, after much reading I found how to define error pages... I have added the following lines to the end of the .htaccess Code: ErrorDocument 301 /index.php ErrorDocument 302 /index.php ErrorDocument 307 /index.php ErrorDocument 400 /index.php ErrorDocument 401 /index.php ErrorDocument 403 /index.php ErrorDocument 404 /index.php It solved my 30x troubles, but when a folder or file does not exist, I am getting an error 500 not 404. And adding ErrorDocument 500 /index.php does nothing to help.
Your problem arises because your API design does not allow you to control and handle incoming requests correctly. I would design and implement such an API differently. 1) You have a single entrypoint for all requests, e.g. named index.php. 2) You have a .htaccess file like this: Code: RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteRule . /index.php [L] 3) In that index.php file, you either handle the API requests directly. Or if you have the API functions in separate files, you simply include them based on the requested URL. Basically like this (simplified example): Code: <?php if(file_exists($_SERVER["REQUEST_URI"])) { // do all kind of security checks to prevent directory traversal etc. If everything is ok, include API file using PHP include function } else { // handle error, as there is no such API file or function }
So after a lot more reading and clawing at the ceiling I now have an .htaccess file that kind of works. Code: # Enable mod_rewrite RewriteEngine On # 1. If the endpoint is not a file or directory, and it does not contain forbidden characters, rewrite to .php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} ^[A-Za-z0-9/_-]+$ RewriteRule ^(.*)$ /$1.php [L] # 2. If the .php file does not exist, rewrite to /index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} ^[A-Za-z0-9/_-]+\.php$ RewriteRule ^(.*)$ /index.php [L] # 3. If the endpoint contains forbidden characters, rewrite to /index.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} !^[A-Za-z0-9/_-]+$ RewriteRule ^(.*)$ /index.php [L] # 4. If the endpoint exists as a file or directory, rewrite to /index.php RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.*)$ /index.php [L] # 5. Serve /index.php as the error page for 30x and 40x errors ErrorDocument 301 /index.php ErrorDocument 302 /index.php ErrorDocument 404 /index.php The only issue I have is I do not want someone calling /path/to/end/point.php I only want it to work with /path/to/end/point
The usual access.log does not really show with what Host-Request the access attempt was done. It's just what the webserver decided to deliver, though yes, welcome to the internet haha. Till is absolutely right, ideally you'd only have public information and a decision maker what to show ( if authenticated ) in web/ folder. Everything else, code, configuration .... belongs to the upper directory, or private/. This should not make a difference in terms of preventing anything. Also the file shouldn't even be there. Though maybe PHP development is not one of your companies most important skills, if your resources allow, https://symfony.com/doc/current/routing.html is an excellent web-framework, stable for years and upgrading, especially for light usages, is very easy. One thing many people new to this do not understand at first: you have a folder src/Controller/ where you can simply put a EndPointController.php which simply has Code similar to the one shown in the linked Example for Routing ( BlogController ) and the https-request to /blog would be "routed" to that specific function and you go from there. however according to chatgpt Basically if the request matches anything .php ( if anything, still, after your previous rules as you use [L] ) it gets rewritten with the matching part before \.php
I used to code a lot back in the days of PHP 4.x Only recently got back into and learned 8.1, then brushed up on 8.2 and now I need to brush up on 8.3 I am specifically using this methodology because it's not one API, but lots of small ones for different problems as well as I will be hosting APIs for my clients. TLDR - I am going to start offering solutions to sync data between platforms. In order to make my life easier, I just keep everything apart. I did solve my problems in the end. One key was to not use .php as the extension, but rather something else and just setup that vhost to pass that file extension to php.
There's still the possibility to have subfolders with different defaultindex file using a different project outside the public web though. seperation is a good thing security wise. If I had different services, I'd not use subfolders but subdomains maybe. Also better to organize. Though not insisting of course, more like wondering Thanks for your reply you solved your issue real seperate vhost subdomains and ideally with their seperate client to have real isolation, otherwise the files would be theoretically accessible by the same group member which can be bad.
You should not hijack threads. It seems to me your question is not relevant to the discussion on this thread. The .htaccess file is a hidden file, it may well be it is not copied in the usual copy. To see if there are any .htaccess files on the host, try this command It should work if command locate is installed. To see if there is .htacces file in a directory, use -a option in ls command, it means to show even hidden files. Now that I have your attention, can you explain why you reasked on Howtoforge years old questions from other forums? Like these: https://forum.howtoforge.com/threads/static-ip-address-configuration.91986/#post-459910 https://forum.howtoforge.com/threads/ip-address-restriction.83357/#post-460032