How to get secureJsonData - plugins

I’m developing an application plugin.
In my understanding, when we try to get a credential from secureJsonData, we need to use data source proxy.
So my questions are:
Do I need to include a data source plugin to use the data source proxy?
According to the documentation, I have to add proxy route configurations in plugin.json file. But how is the routes / url determined?
Thanks,

Do I need to include a data source plugin to use the data source proxy?
You can use secureJsonData credentials in an app route without creating a data source plugin. Routes can be called from any page in your app. It works the same as routes for data source plugins but a plugin proxy module inside Grafana does the work instead of the data source proxy.
But how is the routes / url determined?
The routes are determined by you. You define the url to the backend you want to call to.
Here is an example of a route from the Synthetic Monitoring App:
"routes": [
{
"path": "install",
"method": "*",
"url": "{{ .JsonData.apiHost }}/api/v1/register/install",
"reqRole": "Editor",
"headers": [
{
"name": "Authorization",
"content": "Bearer {{ .SecureJsonData.publisherToken }}"
}
]
}
The path field is the name of the route that you use in your code.
The url field is an external url that the app can call to. When the route is called then the secureJsonData in the headers section is decrypted on the Grafana backend (in the plugin proxy) and added to the headers of the HTTP call.
You control when the call to the route is made in your code (example from the same app):
const { accessToken } = await getBackendSrv().request({
url: `api/plugin-proxy/${meta.id}/install`,
method: 'POST',
data: body,
});
The install path part of the route will be translated into the route url defined in the plugin json by the plugin proxy.

Related

Axios BaseURL not working on certain hosts

Below is how I configured Axios based on the example given on Nuxt.js' website:
.env:
BASE_URL=https://path.to.endpoint
nuxt.config.js:
publicRuntimeConfig: {
axios: {
baseURL: process.env.BASE_URL
}
},
On page load I make this call:
this.$axios.get(`/endpoint`)
Once I deploy my app as a static site it works both on my personal host and on GitHub pages. But on my employer's host, the path to endpoint specified in .env becomes https://localhost:3000 so the API call fails.
Why is the most likely cause of this behaviour?
Alright, from the comments, it looks like you configuration is totally fine from what you've provided and that the team on the other side does have an incorrect setup of the environment variables.
You need to ask where they do host your code and what are the actual values of their env variables. Actually, you will probably need to give it to them since they (usually) cannot guess it by themselves.
Human communication is the next step. ^^

Host a static site single page app in Google Cloud Storage with routes

There are guides and questions all over the place on how to do this, but never really a concrete answer that is satisfactory. Basically, I'm wondering if it's possible to host a static SPA (HTML/CSS/JS) in GCP Cloud Storage.
The main caveat of this is that the SPA has its own routing system (ReactRouter) so I want all paths to be served by index.html.
Most guides will tell you to set the ErrorDocument to index.html instead of 404.html. While this is a clever hack, it causes the site's HTTP response code to be 404 which is a disaster for SEO or monitoring tools. So that will work, as long as I can change the response code.
Is there any way to make this work? I have CloudFlare up and running too but from what I can tell there are no ways to trim the path or change the response status from there.
A good approach here is to use Google App Engine to host a static SPA. https://cloud.google.com/appengine/docs/standard/python/getting-started/hosting-a-static-website
You can use the app.yaml file to map urls to the static file. Here’s an example:
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /
static_files: www/index.html
upload: www/index.html
- url: /(.*)
static_files: www/\1
upload: www/(.*)
Documentation for app.yaml https://cloud.google.com/appengine/docs/standard/python/config/appref
One way to circumvent the problem is to use server-side rendering. In SSR all client requests are passed to a backend app so there's no need for a Cloud Storage-hosted index.html.
This of course comes with its own set of complications but we're avoiding the above-mentioned 404 hack or resorting to any further dependencies like App Engine.
Alternatively you could go with hash-based routing, i.e. paths like https://example.com/#some-path.
A very simple solution would be to just add the index.html file as the 404 fallback. This will always route everything to your single page app.
If you use Cloudflare, you can use a Cloudflare Worker to override the 404 status code, which comes from the Google Cloud Storage error page.
The code for the Worker should look like this:
addEventListener('fetch', event => {
event.respondWith(fetchAndLog(event.request))
})
async function fetchAndLog(req) {
const res = await fetch(req)
console.log('req', res.status, req.url)
if (res.status === 404 && req.method === 'GET') {
console.log('overwrite status', req.url)
return new Response(res.body, {
headers: res.headers,
status: 200
})
}
return res
}
I found it here in the Cloudflare community.

Failed to load resource while consuming OData service

Hello comunnity i need some help, i have my odata service already running and i have an url like this:
https://myclient:port/sap/opu/odata/SAP/servicename_SRV/MaterialListSet
This is my config, which I suppose is wrong.
manifest.json
"dataSources": {
"invoiceRemote": {
"uri": "https://myclient:port/sap/opu/odata/SAP/servicename_SRV/",
"type": "OData",
"settings": {
"odataVersion": "2.0"
}
}
}
.
.
.
"models": {
...
"invoice": {
"dataSource": "invoiceRemote"
}
}
I get these two errors:
Failed to load resource: the server responded with a status of 401 (Unauthorized)
and
Failed to load https://client:port/sap/opu/odata/SAP/odata_SRV/$metadata?sap-language=ES: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:port' is therefore not allowed access. The response had HTTP status code 401.
This line is not good;
"uri": "https://myclient:port/sap/opu/odata/SAP/servicename_SRV/",
This is because you have to use relative URLs, so it should be
"uri": "/sap/opu/odata/SAP/servicename_SRV/",
The reason behind that is simple: your customer for sure has more than one SAP Gateway/Fiori system. So you shouldn't hard code the domain of your development or production system.
Assuming you will eventually deploy your UI5 application to the SAP NetWeaver system, then that system will contain both the oData service AND the UI5 application. And as they will be hosted in the same server, relative URLs will work just fine.
However inside Web IDE this is not enough because if you use relative URLs than SAP Cloud/Web IDE will understand that you are trying to access a resource in the cloud.
That is why you should add/change your neo-app.json file inside your UI5 project. If you have it already than just change it. If you do not have this file inside your project yet, you can easily create it by right-clicking in the project name and choosing New >> HTML5 Application Descriptor. This will create this file in the root of your project. (outside the webapp folder usually present).
Finally, you will have to add a route in this neo-app.json file, like this
{
"path": "/sap/opu/odata",
"target": {
"type": "destination",
"name": "NAME_OF_YOUR_SAP_CLOUD_DESTINATION",
"entryPath": "/sap/opu/odata"
},
"description": "SAP Gateway System"
}
This tells Web IDE to forward every request to a different system under the destionation specified.
This will only work if you have in place an SAP Cloud Connector linking your SAP Cloud account with your SAP NetWeaver on premise system.

I can't get the REST service response in Angular

Inside our company's VPN I can call the web service (which is a REST service) fine, on FF and Chrome. I need to connect to it from Angular 2 though. Now, I tried to call the REST service(which is inside VPN) from Angular 2, in several ways, and I am always getting the message about CORS("No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401." in Chrome and "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://webwassvc-test.servizi.gr-u.it/essigEAIM/rest/monitoring/integrations/all?pag=1. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)." in Firefox). I tried setting the about:config:security.fileuri.strict_origin_policy to false, and it didn't help. The sysadmin on the REST server end told me he opened the server for CORS (cross domain) calls, so I think the problem is on my end, but I don't know what can it be. Any advice, please?
UPDATE: I can access the REST service and get the data from it, through PHP as middleware (localhost/angular2_site/file.php), but not from angular directly (localhost:4200).
Another option it's to manage it with a proxy or load balancer.
If you are developing with anuglar-cli you can use the Proxy To Backend support of the angular-cli. --proxy-config
from the angular-cli readme:
Say we have a api server running on http://localhost:3000/api and we want
all calls to http://localhost:4200/api to go to that server.
We create a file next to projects package.json called proxy.conf.json
with the content
{
"/api": {
"target": "http://localhost:3000",
"secure": false
}
}
You can read more about what options are available here
webpack-dev-server proxy settings
and then we edit the package.json file's start script to be
"start": "ng serve --proxy-config proxy.conf.json", now run it with
npm start
So at the end you can call your services as:
getUsers() : Observable<any>{
return this.http.get('/api/users').map(res => res.json());
}

ionic problem No 'Access-Control-Allow-Origin'

I'm working on an ionic apps.
My problem is: when I try to get data from server I got this:
XMLHttpRequest cannot load https://mywebsite.com/api. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
I already try to add this to .htaccess:
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: *
</ifModule>
And this to my api page (PHP): header('Access-Control-Allow-Origin: *');
but still not working
$http.get(url).success(function(response) {...}
Put it on top of your PHP file like:
<?php
header("Access-Control-Allow-Origin: *");
// then your stuff goes here
?>
Note: as with all uses of the PHP header function, this must be before any output has been sent from the server.
This cors problem has a simple work around in ionic.
Go to your ionic.config.json (previously ionic.project) and add a proxy for example:
{
"name": "proxy-example",
"app_id": "",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://cors.api.com/api"
}
]
}
After that use "/api/" instead of "https://mywebsite.com/api" when you call your api.
For more info:
http://blog.ionic.io/handling-cors-issues-in-ionic/
This is a typical error found when we work with Angular and Ionic, the problem appears because when your app loaded in a browser on your app loads all the content from an origin that comes from your local address http://localhost:8100, then when you want to make any AJAX request sent out to another host than localhost:8100 the request is called from an any point different from the origin its require a CORS(Cross Origin Resource Sharing) preflight request to see if it can access the resource.
The solution is use a Proxy To Backend, with this you can highjack certain urls and send them to a backend server. The implementation is easy:
1.- Modify the file ionic.config.json in the root folder of your project.
2.- Configure your proxy, inside your ionic.config.json file put this, assuming your new host is in http://localhost:3000.
"proxies": [
{
"path": "/endpoints",
"proxyUrl": "http://localhost:3000"
}
]
3.- In your Service change a little the path of your request from this http://localhost:3000/endpoints/any/path/that/you/use to this ../endpoints/any/path/that/you/use(assuming the another host is in localhost:3000 and the context is /endpoints)
If you need more information about this please check http://blog.ionic.io/handling-cors-issues-in-ionic/
premise: This issue is usually only running ionic serve, or using ionic as web app, not in ionic as app.
You can avoid to modify your project and use an extension to disable CORS:
For developing with chrome, something like this:
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi/related
or, if you need it for firefox, something like this:
https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/
IE and Edge sucks so for these you have to manually disable CORS in settings