Skip to content

Front End Use of the Rest API?

So PWA's are a thing now, and I've been testing out the PLC next for our facility. I started to set up a PWA to hit the rest API for PLC Next and got a good old CORS error:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

I'm looking to see what technology PLC Next uses for its app server, but as it is now, I don't think a PWA (or any other browser based front end) can hit the REST API.

Anyone else see this before? Any chance the REST api can be updated to accept the CORS standard?

Best,

Comments

  • We use nginx as the web server. There are resources on the web and many discussions around PWA+CORS+nginx.

    A good starting point is:
    How to create a VueJS PWA on a high performance, secure NGINX infrastructure
    https://www.freecodecamp.org/news/vuejs-pwa-on-nginx-22360ee7a7bf/

    We're happy to help further if you need any more information.
  • @Martin PLCnext Team#

    The info you provided is sort of a basic overview of these technologies. I spent the weekend spelunking your architecture and still cannot pass muster with CORs in a browser. Let me give you my findings so far.

    This is currently the result being produced by the browser:

    QmkpZKv

    The architecture and pathing for the res API is based on nginx and fastCGI. The concerned configurations I have tracked down here:
    /etc/nginx/nginx.conf
    /etc/plcnext/device/Services/Ehmi/nginx_ehmi_location.conf
    

    I have modified these configs to the following:
    nginx.conf
    user www;
    worker_processes  5;
    
    error_log syslog:server=unix:/dev/log,tag=nginx,nohostname,severity=error;
    pid        /run/nginx/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
    
        #disable nginx version number in headers and error pages
        server_tokens off;
        #prevent content type sniffing
        add_header X-Content-Type-Options nosniff;
        #enable XSS filtering
        add_header X-Xss-Protection "1; mode=block" always;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        #filter out all 2xx and 3xx messages to prevent log flooding
        map $status $loggable {
            ~^[23] 0;
            default 1;
        }
    
        access_log syslog:server=unix:/dev/log,facility=auth,tag=nginx,nohostname,severity=info main if=$loggable;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        #gzip  on;
    
        include   /etc/plcnext/device/Services/Ehmi/nginx_ehmi_upstream*.conf;
    
        server {
            listen       80;
    
            #Added these for good measure
            ####################################################################
            add_header Access-Control-Allow-Origin *;
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Request-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
            add_header Access-Control-Allow-Methods "GET, PUT, POST, DELETE, OPTIONS";
            ######################################################################
    
            return 301 https://$host$request_uri;
        }
    
        server {
    
            client_max_body_size 400M;
            #TLS configuration
            listen 443 ssl;
            ssl_certificate         /opt/plcnext/Security/Certificates/https/https_cert.pem;
            ssl_certificate_key     /opt/plcnext/Security/Certificates/https/https_key.pem;
            ssl_ciphers  HIGH:!aNULL:!MD5;
            ssl_prefer_server_ciphers   on;
    
            #charset koi8-r;
           
            #Access log turned on 
            #######################################
            access_log  /var/log/nginx/host.access.log  main;
    
    #####################################################################
    # Every thing below this line remains default ##################################
    #####################################################################
    

    nginx_ehmi_location.conf
    access_log  /var/log/nginx/server.access.log  combined if=$loggable;
    error_log   /var/log/nginx/server.error.log  error;
    
    location ~* ^/_pxc_api/* {
        # pass the _pxc_api json commands to the FastCGI server listening on 127.0.0.1:9999
        fastcgi_pass   fastcgi_backend;     # upstream set above
        fastcgi_buffering off;
        fastcgi_request_buffering off;
        fastcgi_buffers 8 64k;
        fastcgi_buffer_size 64k;            # upstream sends chunks of 64k, as limited by the FCGI header.
        #fastcgi_busy_buffer_size 64k;      # must be equal to or greater than the maximum of the value of fas>
        #fastcgi_connect_timeout 60;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_intercept_errors off;
        fastcgi_keep_conn on;
        fastcgi_next_upstream error off;
        fastcgi_pass_header status;
        fastcgi_pass_header Authorization;
        expires     off;
        add_header Cache-Control "max-age=0, no-cache, no-store, must-revalidate";
    
        # added configurations here
        ##################################################################
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Request-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization";
        add_header Access-Control-Allow-Methods "GET, PUT, POST, DELETE, OPTIONS";
        ###################################################################
    
        include        fastcgi_params;
        access_log  /var/log/nginx/pxcapi.access.log  combined if=$loggable;
        error_log    /var/log/nginx/pxcapi.error.log  error;
        #add_header X-debug-message "location _pxc_api" always;
    }
    #####################################################################
    # Every thing below this line remains default ##################################
    #####################################################################
    

    I have also rebuilt the SSL cert so that it will pass muster with browsers. This gist here is that we needed this line "subjectAltName = IP:192.168.1.10".

    SSL.conf
    [ req ]
    default_bits       = 4096
    distinguished_name = req_distinguished_name
    req_extensions     = req_ext
    prompt             = no
    
    [ req_distinguished_name ]
    commonName                  = 192.168.1.10
    
    [ req_ext ]
    subjectAltName = IP:192.168.1.10
    
    

    Based on all these changes I still get the CORs error in the browser. However, you can see if I call the api directly from something like Postman, I do get the appropriate headers:

    Request
    OPTIONS https://192.168.1.10/_pxc_api/api/auth/auth-token
    Accept: */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-US,en;q=0.9
    Access-Control-Request-Headers: content-type
    Access-Control-Request-Method: POST
    Cache-Control: no-cache
    Connection: keep-alive
    Host: 192.168.1.10
    Origin: http://localhost:8080
    Pragma: no-cache
    Referer: http://localhost:8080/
    Sec-Fetch-Dest: empty
    Sec-Fetch-Mode: cors
    Sec-Fetch-Site: cross-site
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36
    content-type: application/json
    

    Response
    HTTP/1.1 200 OK
    Server: nginx
    Date: Mon, 04 Oct 2021 04:11:20 GMT
    Content-Type: application/json
    Content-Length: 44
    Connection: keep-alive
    Status: 200 OK
    read_time: 2021-10-04T04:11:20.779352Z
    end_time: 2021-10-04T04:11:20.779946Z
    Cache-Control: max-age=0, no-cache, no-store, must-revalidate
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Credentials: true
    Access-Control-Request-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
    Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS
    
    {
      "code": "f77bc27cb0164bdb",
      "expires_in": 600
    }
    

    So you can see that this works, not sure why the browsers are still not working.
  • I am afraid that we (PLCnext Runtime Support) are not so familiar with general web development, so we have been passing your questions to people here with a bit more experience in this area.

    Here is some information on your latest question:
    See this discussion on SO.
    https://stackoverflow.com/questions/36250615/cors-with-postman
    Postman does not enforce CORS. This is why it works in postman.
    This is a general nginx configuration issue [not specific to PLCnext Technology].
    If there are no answers on this topic from the PLCnext Community, perhaps you can try a general nginx forum.
  • Hi @Martin PLCnext Team#

    I was able to resolve this finally. The crux of the issue was that Chrome and Firefox where I tested these both had very specific requirements for accepting a root SSL certificate in combination with a CORS request. I tried a number of certificate configs, and this is what actually worked for future reference:
    ssl.conf
    [ req ]
    default_bits       = 4096
    distinguished_name = req_distinguished_name
    req_extensions     = req_ext
    prompt             = no
    
    [ req_distinguished_name ]
    commonName                  = 192.168.1.10
    
    [ req_ext ]
    subjectAltName = IP:192.168.1.10
    
    

    Also, it should be noted in my examples from he previous posts, I did also have one mistake. In nginx I used the request header by accident:
    Access-Control-Request-Headers:
    

    That should actually be:
    Access-Control-Allow-Headers:
    
  • That's great, I'm glad you found a solution, and thanks for letting us know.
    I will pass this information on to the relevant people here, in case anyone else has a similar issue.
    Thanks again, and enjoy the weekend.
Sign In or Register to comment.