skip to Main Content

I upgraded my Yii2 application version to the latest – 2.0.46 and changed server from apache to Nginx and now I can’t make API GET request from my application using query param auth Given error below

<response>
    <name>Unauthorized</name>
    <message>Your request was made with invalid credentials.</message>
    <code>0</code>
    <status>401</status>
    <type>yiiwebUnauthorizedHttpException</type>
</response> 

My API controller looks like this

public function behaviors(): array
    {
        $behaviors = parent::behaviors();
        $behaviors['authenticator'] = [
            'class' => CompositeAuth::class,
            'authMethods' => [
                QueryParamAuth::class,
            ]
        ];
        $behaviors['language'] = [
            'class' => LanguageSelector::class
        ];
        return $behaviors;
    }

I read that similar problem people had with apache servers and editing .htaccess helped, but what about Nginx? Or maybe problem is with new Yii2 version!?

API call example that I am making – examplesite/api/controller/method/?access-token=myaccesstoken&id=myID&lang=lv-LV
As my application is using only get requests, old version and new version uses same DB and on old version API call like example given (with good data) works fine. Can enyone help me?

UPDATE: Nginx config

server {
  listen 443 ssl;
# server_name exsampleserver;
  server_name exampleserverIP
# add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
  ssl_certificate /etc/nginx/ssl/certdomainexample.crt;
  ssl_certificate_key /etc/nginx/ssl/certdomainexample.key;
  ssl_protocols      TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;
  ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

 access_log /var/log/nginx/app.log upstream_time;
  error_log /var/log/nginx/app-ssl.error.log notice;

 root /srv/www/web/frontend/web;
  index index.php;

 location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

 location /api/ {
    try_files $uri $uri/ /api/index.php?query_string;
  }

 location ~ .php$ {
    include fastcgi_params;

   fastcgi_pass unix:/run/php/php-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    fastcgi_param DOCUMENT_ROOT $realpath_root;
    fastcgi_read_timeout 1200;
    fastcgi_send_timeout 1200;
    fastcgi_connect_timeout 1200;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_pass_header Authorization;
  }

 location ~ /.ht {
    deny all;
  }

 location ~ /.git {
    deny all;
  }

  }

2

Answers


  1. Chosen as BEST ANSWER

    With a help from tech group we founded that working with symlinks in Nginx config $query_params wont work.

    So instead of

        location /api/ {
            try_files $uri $uri/ /api/index.php?query_string;
      }
    

    need to add

    location /api/ {
        try_files $uri $uri/ /api/index.php$is_args$args;
     }
    

    into Nginx config


  2. Directory structure:

    examplesite:
        - api
            + models
            + controllers
            + web
        - backend
            + models
            + controllers
            + web
        + common
        + console
        - frontend
            + models
            + controllers
            + web
        + vendor
        + composer.json
    

    Nginx config for Yii2 advanced app

    This config will allow you to use fallowing domain rules:

    examplesite.test/api   - api folder app
    examplesite.test/admin - backend folder app
    examplesite.test/      - frontend folder app
    

    Disclaimer

    Use this config only in test environments and if you know how nginx works. For production sites better ask for a specialist help.

    server {
    
        #listen *:443 ssl http2;
        listen *:80;    
        server_name examplesite.test;
    
        #include /etc/nginx/ssl-snippets/ssl-snippet.conf;
    
        # LOGS - config
        
        access_log /var/log/nginx/examplesite.access.log;
        error_log /var/log/nginx/examplesite.error.log;
    
        # NGINX - config (sizes, charset, caching, ...)
        
        client_max_body_size 32m;
        client_body_buffer_size 32m;
    
        charset utf-8;
    
        gzip on;
        gzip_types
        text/plain
        text/css
        text/xml
        application/xml
        application/xml+rss
        text/javascript
        application/json
        application/x-javascript
        application/javascript;
    
    
        # BASE ROOT DIRECTORY for Yii advanced app setup. Default must be the path to your app composer.json. Let suppose it in /var/www/examplesite
        
        set $base_root /var/www/examplesite;
        
        # BASE PHP-FPM SOKET - this is passed to nginx fastcgi_pass, uncoment or add needed version
        
        set $php_server unix:/run/php/php7.4-fpm.sock;
        #set $php_server unix:/run/php/php8.0-fpm.sock;
        #set $php_server unix:/run/php/php8.1-fpm.sock;
    
        root $base_root;
        index index.php index.html;
    
        # FRONTEND APP - location config
        
        location / {
            root $base_root/frontend/web;
            try_files $uri $uri/ /frontend/web/index.php$is_args$args;
    
            # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
            location ~ ^/.+.(css|less|js|map|ico|png|jpe?g|gif|webp|svg|eot|ttf|woff|woff2|mp4|mov|swf|txt|pdf)$ {
                expires 365d;
                log_not_found off;
                access_log off;
                try_files $uri =404;
            }
    
            location ~ ^/assets/.+.php(/|$) {
                deny all;
            }
        }
    
    
        # API APP - location config
        
        location /api {
            root $base_root/api/web/;
    
            # redirect to the URL without a trailing slash (uncomment if necessary)
            #location = /api/ {
            #    return 301 /api;
            #}
    
            location = /api {
                try_files $uri /api/web/index.php$is_args$args;
            }
    
            # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
            location ~ ^/api/.+.(css|less|js|map|ico|png|jpe?g|gif|webp|svg|eot|ttf|woff|woff2|mp4|mov|swf|txt|pdf)$ {
                rewrite ^/api(/.+)$ $1 break;
                log_not_found off;
                access_log off;
                try_files $uri =404;
            }
    
            location ~ ^/api/assets/.+.php(/|$) {
                deny all;
            }
    
            try_files $uri $uri/ /api/web/index.php$is_args$args;
        }
    
        # BACKEND APP - location config
        
        location /admin {
            root $base_root/backend/web/;
    
            # redirect to the URL without a trailing slash (uncomment if necessary)
            #location = /admin/ {
            #    return 301 /admin;
            #}
    
            # prevent the directory redirect to the URL with a trailing slash
            location = /admin {
                try_files $uri /backend/web/index.php$is_args$args;
            }
    
            # omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
            location ~ ^/admin/.+.(css|less|js|map|ico|png|jpe?g|gif|webp|svg|eot|ttf|woff|woff2|mp4|mov|swf|txt|pdf)$ {
                rewrite ^/admin(/.+)$ $1 break;
                log_not_found off;
                access_log off;
                try_files $uri =404;
            }
    
            location ~ ^/admin/assets/.+.php(/|$) {
                deny all;
            }
    
            # if your location is "/backend", try use "/backend/backend/web/index.php$is_args$args"
            # bug ticket: https://trac.nginx.org/nginx/ticket/97
            try_files $uri $uri/ /backend/web/index.php$is_args$args;
        }
        
        # PHP FILES HANDLE
        
        location ~ ^/.+.php(/|$) {
            rewrite (?!^/((frontend|api|backend)/web|api|admin))^ /frontend/web$uri break;
            rewrite (?!^/api/web)^/api(/.+)$ /api/web$1 break;
            rewrite (?!^/backend/web)^/admin(/.+)$ /backend/web$1 break;
    
            fastcgi_pass $php_server;
            fastcgi_split_path_info ^(.+.php)(.*)$;
            include /etc/nginx/fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            try_files $fastcgi_script_name =404;
        }
        
        # OTHER LOCATIONS AND RESTRICTIONS
        
        location =  /robots.txt     { access_log off; log_not_found off; }
        location =  /favicon.ico    { access_log off; log_not_found off; }
        location ~* /.             { access_log off; log_not_found off; deny all; }
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search