Search code examples
wordpressnginxhttp-redirectconfignginx-config

How to redirect a web page with a Hash in URL NGINX Ubuntu Server


I have an issue to make my reset password service functionally, I send via API a hash in the URL, so the client receive a URL like https://mydomain.com.mx/?hash=hash_code
I need to set a redirect for this URL, so when the client click on it the site must redirect to https://mydomain.com.mx/recovery/?hash=hash_code

I already try different settings as rewrite or try file. The closest to working was

if ($arg_hash) {
      return 301 https://mydomain.com.mx/recovery/?hash=$arg_hash;
  }

But I get an error, too many to redirects, please if you can help me, I'll be grateful

This is my conf file, I use wordpress for this website

Important I can't edit the url that comes to the user should be kept as https://mydomain.com.mx

# Default server configuration
#

      log_format custom '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';

server {
        root /var/www/html/mydomain.com.mx;
        access_log /var/log/nginx/mydomain.com.mx.access.log custom;
        error_log /var/log/nginx/mydomain.com.mx.error.log debug;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html index.php;
        server_name www.mydomain.com.mx mydomain.com.mx;

        # BEGIN Converter for Media
        set $ext_avif ".avif";
        if ($http_accept !~* "image/avif") {
            set $ext_avif "";
        }

        set $ext_webp ".webp";
        if ($http_accept !~* "image/webp") {
            set $ext_webp "";
        }
        # nginx block xmlrpc.php requests
        location /xmlrpc.php {
        deny all;
        }
        location ~ /wp-content/(?<path>.+)\.(?<ext>jpe?g|png|gif|webp)$ {
            add_header Vary Accept;
            add_header Cache-Control "private";
            expires 365d;
            try_files
                /wp-content/uploads-webpc/$path.$ext$ext_avif
                /wp-content/uploads-webpc/$path.$ext$ext_webp
                $uri =404;
        }
        # END Converter for Media

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ =404;
                try_files $uri $uri/ /index.php?$args;
        }

        # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
        #
        #       # With php-fpm (or other unix sockets):
                fastcgi_pass unix:/run/php/php8.3-fpm.sock;
                fastcgi_read_timeout 120;
        #       # With php-cgi (or other tcp sockets):
        #       fastcgi_pass 127.0.0.1:9000;
        }
        gzip on;
        gzip_comp_level 6;
        gzip_min_length 1000;
        gzip_proxied any;
        gzip_disable "msie6";
#  gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
        gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/xhtml+xml application/xml font/eot font/otf font/ttf image/svg+xml text/css text/javascript text/plain text/xml;
  # Enable Brotli compression
        brotli on;
        brotli_comp_level 6;
        brotli_types text/xml image/svg+xml application/x-font-ttf image/vnd.microsoft.icon application/x-font-opentype application/json font/eot application/vnd.ms-fontobject application/javascript font/otf application/xml application/xhtml+xml text/javascript  application/x-javascript text/plain application/x-font-truetype application/xml+rss image/x-icon font/opentype text/css image/x-win-bitmap;

        location ~*\.(?:css(\.map)?|js(\.map)?|ico|cur|heic|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
         expires 90d;
         access_log off;
         }

        location ~*\.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
         add_header Access-Control-Allow-Origin "*";
         expires 90d;
         access_log off;
         }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
                deny all;
        }

        location ~ /\.user.ini {
                deny all;
        }

        location /wp-json/ {
        try_files $uri $uri/ /index.php?$is_args$args;
        }

        # if ($arg_hash) {
        #    return 301 https://mydomain.com.mx/recovery/?hash=$arg_hash;
        #}


    listen [::]:443 ssl http2;# managed by Cer tbot
    listen 443 ssl http2; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mydomain.com.mx/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com.mx/privkey.pem; # managed by Certbot
    #include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    include perfect-forward-secrecy.conf;
    #ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = mydomain.com.mx) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    server_name www.mydomain.com.mx mydomain.com.mx;
    listen [::]:80;
    listen 80;
#   return 404; # managed by Certbot


}

Solution

  • You get a redirection loop because if ($arg_hash) matches both //example.com/?hash=xxx and //example.com/recovery/?hash=xxx

    One solution is to modify your if statement to only match the first case.

    For example:

    if ($request_uri ~* "^/\?hash=") {
        return 301 /recovery/?hash=$arg_hash;
    }