김태우
김태우

Reputation: 1255

How to get Superset Token?? (for use Rest api)

I attempted to request a REST request to see the document below. But do not work. https://superset.apache.org/docs/rest-api

request: curl -XGET -L http://[IP:PORT]/api/v1/chart

response: {"msg":"Bad Authorization header. Expected value 'Bearer <JWT>'"}

The Superset installation has been on PIP and was also Helm Chart. But all are the same. helm: https://github.com/apache/superset

How should I order a REST API?

Upvotes: 9

Views: 20292

Answers (6)

Hung
Hung

Reputation: 81

Thanks @Ferris for this visual solution!

To add to this, you can also create the appropriate API call with Python just like following:

 import requests

 api_url = "your_url/api/v1/security/login"
 payload = {"password":"your password", 
            "provider":"db",
            "refresh":True,
            "username":"your username"
 }
 response = requests.post(api_url, json=payload)
 # the acc_token is a json, which holds access_token and refresh_token

 access_token = response.json()['access_token']

 # no get a guest token
 api_url_for_guesttoken = "your_url/api/v1/security/guest_token"
 payload = {}

 # now this is the crucial part: add the specific auth-header
 response = requests.post(api_url_for_guesttoken , json=payload, headers={'Authorization':f"Bearer {access_token}"}) 

print(response)

Upvotes: 3

kenske
kenske

Reputation: 2354

I was running into issues with the API requiring a session token and a referrer for some endpoints. I figured out you need to save the cookie from the csrf_token request and use it for subsequent requests. Here is my full example (requires curl and jq):

#!/bin/bash

set -e


host="https://${SUPERSET_HOSTNAME}"

echo "Fetching access token"
json=$(curl -s "${host}/api/v1/security/login" \
        -X POST \
        -H 'Content-Type: application/json' \
        -d '{"password": "'${SUPERSET_API_PASSWORD}'", "provider": "db", "refresh": true, "username": "'${SUPERSET_API_USERNAME}'"}')

access_token=$(echo $json | jq -r ".access_token")

if [ "null" ==  "$access_token" ]; then
    echo "Failed to fetch access token"
    exit 1
fi


echo "access_token = $access_token"

echo "Fetching csrf token"
json=$(curl -s --location GET "${host}/api/v1/security/csrf_token/" \
        --header "Authorization: Bearer $access_token" \
        --cookie-jar cookie.txt)
csrf_token=$(echo $json | jq -r ".result")
echo "csrf_token = $csrf_token"

# Get session from cookie file
session=$(cat cookie.txt | grep session | awk '{print $7}')
echo "session = $session"



referer="${host}/databaseview/list/"

curl -s "$url" \
        --header "X-CSRFToken: $csrf_token" \
        --header "Authorization: Bearer $access_token" \
        --header 'Content-Type: application/json' \
        --cookie "session=${session}" \
        --referer "${referer}" \
        -X PUT  \
        -d "$params"

echo -e "\nDone!"

Upvotes: 0

jvanheijzen
jvanheijzen

Reputation: 339

I thought I would share, since it took me a couple of days to sort this out. If you are aiming to programmatically import things using curl, this is how I was able to do it. This is for a development server and passwords are in plain text. Obviously, use proper precautions when transitioning to a production server.

json=$(curl -k 'http://localhost:8088/api/v1/security/login' \
        -X POST -H 'Content-Type: application/json' \
        -d '{"password": "admin", "provider": "db", "refresh": true, "username": "admin"}') \
&& access_token=$(echo $json | sed "s/{.*\"access_token\":\"\([^\"]*\).*}/\1/g") \
&& echo "access_token = $access_token"

json=$(curl --location GET "http://localhost:8088/api/v1/security/csrf_token/" --header "Authorization: Bearer $access_token") \
&& csrf_token=$(echo $json | sed "s/{.*\"result\":\"\([^\"]*\).*}/\1/g") \
&& echo "csrf_token = $csrf_token"

curl --location --request POST "http://localhost:8088/api/v1/dashboard/import/" \
--header "X-CSRFToken: $csrf_token" \
--header "Authorization: Bearer $access_token" \
--form "[email protected];type=application/x-zip-compressed" \
--form "overwrite=true"

Upvotes: 5

Saiqul Haq
Saiqul Haq

Reputation: 2397

open http://localhost:8080/swagger/v1, assuming http://localhost:8080 is your Superset host address then find this section enter image description here

the response would be like this

{
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjU0MzQ2OTM5LCJqdGkiOiJlZGY2NTUxMC0xMzI1LTQ0NDEtYmFmMi02MDc1MzhjZDcwNGYiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoxLCJuYmYiOjE2NTQzNDY5MzksImV4cCI6MTY1NDM0NzgzOX0.TfjUea3ycH77xhCWOpO4LFbYHrT28Y8dnWsc1xS_IOY",
    "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY1NDM0NjkzOSwianRpIjoiNzBiM2EyZDYtNDFlNy00ZDNlLWE0NDQtMTRiNTkyNTk4NjUwIiwidHlwZSI6InJlZnJlc2giLCJzdWIiOjEsIm5iZiI6MTY1NDM0NjkzOSwiZXhwIjoxNjU2OTM4OTM5fQ.OgcctNnO4zTDfTgtHnaEshk7u-D6wOxfxjCsjqjKYyE"
}

Upvotes: 6

Ferris
Ferris

Reputation: 5611

Thank @andrewsali commented on this github issue, I finally figure out how to access the superset REST API by python code.

import requests
from bs4 import BeautifulSoup
import json
def get_supetset_session():
    """
    # http://192.168.100.120:8088/swagger/v1
    url = f'http://{superset_host}/api/v1/chart/'
    r = s.get(url)
    # print(r.json())    
    """
    superset_host = '192.168.100.120:8088' # replace with your own host
    username = 'YOUR_NAME'
    password = 'YOUR_PASSWORD'

    # set up session for auth    
    s = requests.Session()
    login_form = s.post(f"http://{superset_host}/login")
    # get Cross-Site Request Forgery protection token
    soup = BeautifulSoup(login_form.text, 'html.parser')
    csrf_token = soup.find('input',{'id':'csrf_token'})['value']
    data = {
        'username': username,
        'password': password,
        'csrf_token':csrf_token
    }
    # login the given session
    s.post(f'http://{superset_host}/login/', data=data)
    print(dict(s.cookies))
    return s

DEMO

# s = get_supetset_session()
base_url = 'http://192.168.100.120:8088'
def get_dashboards_list(s, base_url=base_url):
    """## GET List of Dashboards"""
    url = base_url + '/api/v1/dashboard/'
    r = s.get(url)
    resp_dashboard = r.json()
    for result in resp_dashboard['result']:
        print(result['dashboard_title'], result['id'])

s = get_supetset_session()
# {'session': '.eJwlj8FqAzEMRP_F5z1Islay8jOLJcu0NDSwm5xK_r0uPQ7DG978lGOeeX2U2_N85VaOz1FuxVK6JIHu1QFhGuEOk5NG8qiYGkJ7rR3_Ym-uJMOzJqySeHhIG8SkNQK6GVhTdLf0ZMmG6sZGQtiQ1Gz0qYiUTVoHhohZthLXOY_n4yu_l0-VKTObLaE13i2Hz2A2rzBmhU7WkkN1cfdH9HsuZoFbeV15_l_C8v4F4nBC9A.Ypn16Q.yz4E-vz0gp3EmJwv-6tYIcOGavU'}
get_dashboards_list(s)

enter image description here enter image description here enter image description here enter image description here

Upvotes: 1

Arkit Patel
Arkit Patel

Reputation: 91

Check the security section of the documentation you have linked. It has this API ​/security​/login, you can follow the JSON parameter format and get the JWT bearer token. Use that token to send in the Header of your other API calls to superset.

Upvotes: 2

Related Questions