-1

I have this friendly url that i'm using on my website:

https://myexample.com/post/10/post-title

I'm trying to do something that deny user to access directly in parameters value. For example, if user try to put another id inside url above, htaccess will redirect him to 404 page.

Below is my htaccess code that convert my url get parameters to friendly url and works like a charm:

RewriteEngine On
RewriteRule ^post/([^/]*)/([^/]*)$ /news?id=$1&title=$2 [L]

In this case, how can i improve my htaccess to do this?

Any help i appreciate.

Michel
  • 15
  • 8
  • There is no way to check whether that ID `10` exists, or belongs to the post with slug `post-title`, on this level. You should handle this from inside your script, which makes the actual database request(?). – 04FS Sep 25 '20 at 06:41
  • Thanks for your feedback @04FS. Got it. Actually when i try to empty id parameter inside url, i got 500 internal server error even though I have GET rule to redirect if id is empty. I'll try to implement some rule in php to redirect to 404 page if some parameter not exists or if GET value was change. – Michel Sep 25 '20 at 11:50
  • FYI, _externally_ redirecting to a 404 document is a wrong thing to do. All clients that rely on the status code information (such as search engine bots), will then not be able to associate the 404 status code with the originally requested URL any more - _because_ you redirected elsewhere, and only that second request got the 404 response then. If you determine that you have a “case of 404” in your PHP script at some point, then that script should respond with a 404 directly, _not_ redirect to a different 404 document URL. – 04FS Sep 25 '20 at 11:55
  • I see. But in this case, if i want to redirect user if url is incorrect? For example, if i try to edit or try to delete this parameter /64057693/ of this question page, SO will give me a *Page not found*. In this case is this related with my doubt? – Michel Sep 25 '20 at 12:25
  • _“if i try to edit or try to delete this parameter /64057693/ of this question page, SO will give me a Page not found.”_ - and that is the appropriate response, is it not? – 04FS Sep 25 '20 at 12:31
  • Yes, but in this case how could i found a way to applicate a rule to redirect users to *Page not found * if some user edit or type some worng information inside url? Anyway, i appreciate your attention. – Michel Sep 25 '20 at 12:52

1 Answers1

0

I found a way to solve my problem and works fine:

My .htaccess:

RewriteEngine On
RewriteRule ^post/?(.*)/([^/]*)$ /news?id=$1&title=$2 [L]

First, i implemented a function that replace spaces and special characters on title parameter on news.php:

function sanitizeString($str) {
    $str = preg_replace('/[áàãâä]/ui', 'a', $str);
    $str = preg_replace('/[éèêë]/ui', 'e', $str);
    $str = preg_replace('/[íìîï]/ui', 'i', $str);
    $str = preg_replace('/[óòõôö]/ui', 'o', $str);
    $str = preg_replace('/[úùûü]/ui', 'u', $str);
    $str = preg_replace('/[ç]/ui', 'c', $str);
    $str = preg_replace('/[^a-z0-9]/i', '-', $str);
    $str = preg_replace('/_+/', '-', $str);
    return $str;
}

And then i created a script on news.php that check if id and title parameters are related correctly on MySql:

include 'connection.php';

$stmt = $db -> prepare('SELECT id, title FROM posts WHERE id = ?');

$id = $_GET['id'];

$stmt -> bind_param('i', $id);
$stmt -> execute();
$stmt -> store_result();
$stmt -> bind_result($postID, $title);
$stmt -> fetch();
$stmt -> close();
$db -> close();

$postTitle = sanitizeString(trim(strtolower($title)));

if($_GET['id'] != $postID || $_GET['title'] != $postTitle){
    
    header('location: /404.html');
    exit();
    
}else{
    
    echo 'Everything Fine';
    
}

Basicly, based on code above, if an user try to manipulate parameters inside URL like id /10/ and title /post-title:

https://myexample.com/post/10/post-title

for example, the script will redirect user to 404 error page or Page not found or some custom page.

If someone has a better way to improve this, please tell here.

Hope that question can help another persons.

Michel
  • 15
  • 8