Deploying Portus in GCP with an Nginx Ingress load balancer implemented. Portus loads up just fine but when trying to use the application and fill out some of the forms I get the following error:
VM798:1 Mixed Content: The page at 'https://staging.foo.bar/admin/registries/new' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://staging.foo.bar//api/v1/registries/validate?name=devreg&hostname=staging-foo-barregistry%3A5000&external_hostname=&use_ssl=false&force=false&only%5B%5D=hostname'. This request has been blocked; the content must be served over HTTPS.
Nginx configuration: https://github.com/kubic-project/caasp-services/blob/master/contrib/helm-charts/portus/templates/nginx-configmap.yaml
Environment:
mount API::RootAPI => "/"
So I've made sure to check the code for manual http calls and didn't see anything. And I've spent a day now trying to dig through rails docs and nginx docs to see what is causing some of the app to load properly with ssl and the API to not follow the same rules
----- Update 1 ------ Upon further investigation, It looks like it has something to do with Vue validator. Checking the developer tools revealed the following:
curl 'http://staging.foo.bar//api/v1/registries/validate?name=devreg&hostname=st&external_hostname=&use_ssl=false&force=false&only%5B%5D=name' -X OPTIONS -H 'Access-Control-Request-Method: GET' -H 'Origin: https://staging.foo.bar' -H 'Access-Control-Request-Headers: x-csrf-token' --compressed
And it looks like the root url is being called here:
javascript:
window.API_ROOT_URL = '#{root_url}';
root_url is set to / as mentioned above.
However, analyzing the Vue code closer revels:
Vue.http.options.root = window.API_ROOT_URL;
Vue.http.interceptors.push((_request, next) => {
window.$.active = window.$.active || 0;
window.$.active += 1;
next(() => {
window.$.active -= 1;
});
});
Vue.http.interceptors.push((request, next) => {
if ($.rails) {
// eslint-disable-next-line no-param-reassign
request.headers.set('X-CSRF-Token', $.rails.csrfToken());
}
next();
});
// we are not a SPA and when user clicks on back/forward
// we want the page to be fully reloaded to take advantage of
// the url query params state
window.onpopstate = function (e) {
// phantomjs seems to trigger an oppopstate event
// when visiting pages, e.state is always null and
// in our component we set an empty string
if (e.state !== null) {
window.location.reload();
}
};
Vue.config.productionTip = process.env.NODE_ENV !== 'production';
Params are set to use SSL in the query
params do
requires :name,
using: API::Entities::Registries.documentation.slice(:name)
requires :hostname,
using: API::Entities::Registries.documentation.slice(:hostname)
optional :external_hostname,
using: API::Entities::Registries.documentation.slice(:external_hostname)
requires :use_ssl,
using: API::Entities::Registries.documentation.slice(:use_ssl)
optional :only, type: Array[String]
end
Path types ImplementationSpecific : With this path type, matching is up to the IngressClass. Implementations can treat this as a separate pathType or treat it identically to Prefix or Exact path types. Exact : Matches the URL path exactly and with case sensitivity.
ingress-nginx is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer. Learn more about Ingress on the main Kubernetes documentation site.
I'm not sure about how your app works, and the mechanics of what data is being passed where, but I suspect you might need to be passing use_ssl=true
in the querystring parameter to your /validate
endpoint.
Currently, use_ssl=false
is being passed, which is likely returning a non-SSL response.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With