Import dashboard in superset through api - apache-superset

I'm trying to import the Superset dashboard through API but currently not successful yet.
I'm following Superset API docs to import with endpoint
/api/v1/dashboard/import
My import payload as bellow:
POST /api/v1/dashboard/import/ HTTP/1.1
Host: localhost:8088
Authorization: Bearer <access token>
Content-Length: 289
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="formData"; filename="20210615_065115.json"
Content-Type: application/json
(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="overwrite"
True
----WebKitFormBoundary7MA4YWxkTrZu0gW
I got a response with status 200 but the dashboard not import, and in the preview response on postman a got output as the image below:
Anybody can help with this issue?
Thanks.

Superset documentation isn't very clear about this but I finally managed to solve this problem.
As you can see your response is redirecting you to a login page.
What you need to do is to first make a GET request to /api/v1/security/csrf_token/
And add header in your request to /api/v1/dashboard/import
'X-CSRFToken': csrf_token
Another thing incorrect thing in the documentation is that Content-type is not multipart/form-data; but it is text/html; charset=utf-8
So basically in your call you don't need to pass Content-type in headers
Python example:
import requests
headers = {
'accept': 'application/json',
'Authorization': f'Bearer {jwt_token}',
'X-CSRFToken': csrf_token
}
files = {
'formData': (
dashboard_path,
open(dashboard_path, 'rb'),
'application/json'
)
}
response = self.session.post(url, files=files, headers=headers)
EDIT 30.08.2021
I've noticed that for some reason when I was running Superset with AUTH_TYPE = AUTH_OAUTH on production the solution above stopped working.
It requires additionally header Referer to be included in headers, so more safe option would be
import requests
headers = {
'accept': 'application/json',
'Authorization': f'Bearer {jwt_token}',
'X-CSRFToken': csrf_token,
'Referer': url
}
files = {
'formData': (
dashboard_path,
open(dashboard_path, 'rb'),
'application/json'
)
}
response = self.session.post(url, files=files, headers=headers)

Related

CORS on AWS API Gateway and S3

I am calling an AWS API which uses lambda function. I am calling it from a HTML page which is hosted in S3 (static web hosting). While calling the API I get CORS error:
Access to XMLHttpRequest at '' from origin
'' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I have tried it after enabling CORS on API, Specifying CORS on S3 bucket but it is not working.
Seems, I am missing the right place where CORS headers are to be specifies.
Additional information:
I get following information in chrome developer tool
**Response Headers**
content-length: 42
content-type: application/json
date: Mon, 24 Feb 2020 04:28:51 GMT
status: 403
x-amz-apigw-id: IYmYgFQvoAMFy6Q=
x-amzn-errortype: MissingAuthenticationTokenException
x-amzn-requestid: 79b18379-383d-4ddb-a061-77f55b5727c3
**Request Headers**
authority: apiid-api.us-east-1.amazonaws.com
method: POST
path: /Prod
scheme: https
accept: application/json, text/javascript, */*; q=0.01
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,hi;q=0.8
access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
access-control-allow-methods: GET, OPTIONS
access-control-allow-origin: https://apiid.execute-api.us-east-1.amazonaws.com/Prod
content-length: 117
content-type: application/json; charset=UTF-8
origin: http://example.com
referer: http://example.com/
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/79.0.3945.130 Safari/537.36
Lambda function code:
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var RECEIVER = 'example#gmail.com';
var SENDER = 'example#gmail.com';
var response = {
"isBase64Encoded": false,
"headers": { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'},
"statusCode": 200,
"body": "{\"result\": \"Success.\"}"
};
exports.handler = function (event, context) {
console.log('Received event:', event);
sendEmail(event, function (err, data) {
context.done(err, null);
});
};
function sendEmail (event, done) {
var params = {
Destination: {
ToAddresses: [
RECEIVER
]
},
Message: {
Body: {
Text: {
Data: 'name: ' + event.name + '\nphone: ' + event.phone + '\nemail: ' + event.email + '\ndesc: ' + event.desc,
Charset: 'UTF-8'
}
},
Subject: {
Data: 'Website Referral Form: ' + event.name,
Charset: 'UTF-8'
}
},
Source: SENDER
};
ses.sendEmail(params, done);
}
No 'Access-Control-Allow-Origin' header is present on the requested resource.
This is saying that the resource you requested, your Lambda via API Gateway, is not returning an Access-Control-Allow-Origin header in its response; the browser is expecting the CORS headers in the response from the API (possibly because of an OPTIONS request), but the response doesn’t have them.
You’ve not said so specifically but I’m assuming you’re using a Lambda proxy integration on your API gateway. To solve your issue, add a Access-Control-Allow-Origin: * header to the response your Lambda returns. You’ve not specified the language your Lambda is written in, or provided your Lambda code, but if it was in NodeJS, a snippet of what you‘d return might look something like:
const result = {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*',
// other required headers
},
body: object_you_are_returning
};
return result;
Very surprisingly, the reason seems to be “the client-side shouldn't have 'Access-Control-Allow-Origin': '*'. That should only be in the Lambda code, apparently, and adding it to the jQuery code will cause the preflight to fail for some reason.”
https://github.com/serverless/serverless/issues/4037#issuecomment-320434887
Supplement information following the comment:
I also tried to use ajax hosted in S3 to call my Lambda function through API Gateway. I have tried many suggestions especially this solution (http://stackoverflow.com/a/52683640/13530447), but none of them works for me. In the developer-mode of Chrome, I kept seeing the error "Access to XMLHttpRequest at '[my API]' from origin '[my S3 website]' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response." I solved this by removing 'Access-Control-Allow-Origin': '*' in ajax. Still take the solution (http://stackoverflow.com/a/52683640/13530447) as an example, it will work by changing
$.ajax(
{
url: 'https://npvkf9jnqb.execute-api.us-east-1.amazonaws.com/v1',
headers: {'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*'
},
crossDomain: true,
type:'GET',
dataType: 'text',
success: function(data)
{
window.alert(data);
}
});
into
$.ajax(
{
url: 'https://npvkf9jnqb.execute-api.us-east-1.amazonaws.com/v1',
headers: {'Content-Type': 'application/json'},
crossDomain: true,
type:'GET',
dataType: 'text',
success: function(data)
{
window.alert(data);
}
});

missing token ‘access-control-allow-origin’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel

I'm trying to connect my a React Application to a Django Server. The React application is running on http://127.0.0.1:3000/
The response headers has Access-Control-Allow-Origin: http://127.0.0.1:3000 set, yet I am still seeing the error.
I am currently using Django's corsheaders package as recommended everywhere. Decent example of the recommendation How can I enable CORS on Django REST Framework.
But I have also tried custom middleware at this point.
My Django Settings.py file contains the following
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
]
Django is on 8000, React on 3000
CORS_ORIGIN_WHITELIST = [
'http://127.0.0.1:3000',
'http://localhost:3000',
'http://127.0.0.1:8000',
'http://localhost:8000',
]
My request in react looks like this. (It works when I run it directly, not through the browser)
const fetch = require('node-fetch')
const response = await fetch(
url,
{
json: true,
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
Accept: '*/*',
'Content-Type': 'application/json'
}
}
)
Again, it is so strange that I am making the request from http://127.0.0.1:3000 and the response headers has Access-Control-Allow-Origin: http://127.0.0.1:3000 but for some reason it is still failing.
Oh the error message in the browsers console is
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8000/query/?date=2019-10-25. (Reason: missing token ‘access-control-allow-origin’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://127.0.0.1:8000/query/?date=2019-10-25. (Reason: CORS request did not succeed).
Any help would be awesome! Thanks
#sideshowbarker figured it out. It was because I was sending headers in my request.
Changing
const fetch = require('node-fetch')
const response = await fetch(
url,
{
json: true,
method: 'GET',
headers: {
'Access-Control-Allow-Origin': '*',
Accept: '*/*',
'Content-Type': 'application/json'
}
}
)
to
const fetch = require('node-fetch')
const response = await fetch(
url,
{
json: true,
method: 'GET'
}
)
Immediately fixed the issue! Thank you!

Json Web Token, Axios 401-Unauthorized, Django, Vue.js

Every time i do a GET request to API from FrontEnd or POSTMAN to secured (isAuthenticated) content, i get 401 error(Unauthorized).
I have two servers:
1.Django, django-rest-framework, with Json Web Token.(API)
2.Vue.js
api endpoints:
Registration (AllowAny): http://holykrava.hopto.org:8002/user-api/register/
Login (AllowAny): http://holykrava.hopto.org:8002/user-api/get-token/
List of Users (IsAuthenticated): http://holykrava.hopto.org:8002/user-api/user-list/
Vue-Part
<script>
//import {HTTP} from './http-common';
import axios from 'axios'
export default {
created() {
//let tokenOld = localStorage.getItem('token')
let token = this.$store.state.token
axios.get(
'http://holykrava.hopto.org:8002/user-api/user-list/',
{headers: {
authorization: token
}}
)
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error);
})
}
}
</script>
Chrome Dev Tool (Network-Logs)
General-Headers:
Request URL: http://holykrava.hopto.org:8002/user-api/user-list/
Request Method: GET
Status Code: 401 Unauthorized
Remote Address: 188.190.62.145:8002
Referrer Policy: no-referrer-when-downgrade
Request-Headers:
Provisional headers are shown
Accept: application/json, text/plain, */*
Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6Im11dGFwdXRhIiwiZXhwIjoxNTMxODUxODg0LCJlbWFpbCI6IiIsIm9yaWdfaWF0IjoxNTMxNzY1NDg0fQ.LGji_eCDVIvGpQ9xDEO2QAISEEW9FpHVcwRl6Oz9cCM
Origin: http://localhost:8080
Referer: http://localhost:8080/?
Response-Headers:
Access-Control-Allow-Origin: *
Allow: GET, HEAD, OPTIONS
Content-Length: 58
Content-Type: application/json
Date: Mon, 16 Jul 2018 19:34:45 GMT
Server: WSGIServer/0.2 CPython/3.6.4
Vary: Accept
WWW-Authenticate: JWT realm="api"
X-Frame-Options: SAMEORIGIN
IT Works in Terminal like this:
get token:
curl -X POST -d "username=userusername&password=userpassword" http://holykrava.hopto.org:8002/user-api/get-token/
pass token:
curl -H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0MCwidXNlcm5hbWUiOiJ1c2VydXNlcm5hbWUiLCJleHAiOjE1MzE4NDAxNTAsImVtYWlsIjoiIiwib3JpZ19pYXQiOjE1MzE3NTM3NTB9.SoITxagpmbviEFl_Iy086Jy0KgAUNV0WW-a3wMM_Fos" http://holykrava.hopto.org:8002/user-api/user-list/
corsheaders.middleware.CorsMiddleware, installed
CORS_ORIGIN_ALLOW_ALL = True
Default Authintication Class:
'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
i spend two days trying to figure out whats wrong, but failed
looking for some1 who can help! thanks.

react native 0.50.3 authorization header not sent

I am using react-native 0.50.3 to send token authenticated requests to my backend and unfortunately the 'authorization' part of the header is not send by the fetch.
My code is the following :
async componentDidMount() {
var mytoken = await AsyncStorage.getItem('token');
fetch('http://myserver:8000/home', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Origin': '',
'Content-Type': 'application/json',
'authorization': 'Bearer ' + mytoken
}
})
.then((response) => response.json())
.then((content) => {
this.state.user = content.user;
})
.done();
}
And on my server side, the wireshark trace shows that the authorization is not in the request header :
Hypertext Transfer Protocol
GET /home/ HTTP/1.1\r\n
Host: 10.150.21.124:8000\r\n
Content-Type: application/json\r\n
Origin: \r\n
Accept: application/json\r\n
User-Agent: Expo/2.3.0.1012011 CFNetwork/893.14 Darwin/17.3.0\r\n
Accept-Language: en-us\r\n
Accept-Encoding: gzip, deflate\r\n
Connection: keep-alive\r\n
\r\n
[Full request URI: http://10.150.21.124:8000/home/]
[HTTP request 1/1]
[Response in frame: 2326]
And of course I get a 401 unhautorized by the server.
My backend is a django API with CORS installed and CORS_ORIGIN_ALLOW_ALL = True and ALLOWED_HOSTS = ['*'].
The versions of my developments framework elements are the following :
npm 4.6.1
node v9.3.0
react-native-cli 2.0.1
One important update, the request I try to do with react-native works like a charm with postman. So the issue is not located on the server side.
Thank you for your help.
Alex.
try with trailing slash, in url address:
fetch('http://myserver:8000/home/', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Origin': '',
'Content-Type': 'application/json',
'authorization': 'Bearer ' + mytoken
}
})
.then((response) => response.json())
.then((content) => {
this.state.user = content.user;
})
.done();
Pooya's answer worked for me by adding the trailing slash on the request object. Strange because it worked on postman without the trailing slash hence the challenge in debugging. P.S i am also using the same stack, django, django REST framework (DRF) react native
fetch('http://mywebsite.com/posts/', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token
}
})

FineUploaderS3 (4.4) Accept Header in Firefox

I'm having a problem with FineUploader 4.4 in Firefox. As you know, Firefox sends the following HTTP accept header by default:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
But since AmazonS3 returns JSON data after I upload a file via POST with FineUploader, I need to override FineUploader to send an application/json Accept header:
$('#demoUploader').fineUploaderS3({
autoUpload: true,
request: {
endpoint: "https://s3.amazonaws.com/myapp",
accessKey: "AKIAJ4VQLGW68A2Y6JLQ",
customHeaders: { 'Accept': 'application/json' }
},
... etc
But this is not working. FineUploaderS3 ignores my customHeader option and still sends the default Accept header. What am I doing wrong?
Solved! Thanks #RayNicholus
I had to add the customHeaders option to my uploadSuccess endpoint in order to force Firefox to send the application/json Accept header.
uploadSuccess: {
endpoint: "/api/amazons3/uploadSuccessful",
customHeaders: { 'accept': 'application/json' }
},