Add jwt token in the query params

Summary

A workaround to enhance the security when embedding a streamlit app.
User loginned in, and with the right permittion will be granted to visit the embedded page within an expiration period.

Code

Code to generate the url to embed:

import jwt,time
ST_SECRET_KEY = ''
def url_gen():
    # call this method to generate the url 
    payload = {
        "resource": "1", # app page id or other 
        "exp": round(time.time()) + (60 * 1) # 1 minute expiration
    }
    token = jwt.encode(payload, ST_SECRET_KEY, algorithm="HS256")
    url = f'xxxx/?embedded=true&_jwt={token}' # embed this url
    return url

# django view for example
@login_required(login_url="user:login")
def embed_frame(request, required_perm=None):
    if required_perm and not request.user.has_perm(required_perm):
        return redirect("unauthorized")
    url = url_gen()
    context = {'embed_url': url}
    return render(request, 'pages/embed_page.html', context)

Streamlit app:

import streamlit as st
import jwt
import time

ST_SECRET_KEY = ''
def auth():
    query = st.experimental_get_query_params()
    if token:=query.get('_kw'):
        payload = jwt.decode(token[0], ST_SECRET_KEY, algorithms=["HS256"])
        if payload['resource'] == '1' and payload['exp'] > round(time.time()):
            return True
    return False

def page():
    st.write("get it!")

if __name__ == '__main__':
    if auth():
        page()
    else:
        st.write("UnAuth")
3 Likes

Thanks @Andres-Peng for sharing this with the community! This would definitely come in handy.

Thank you, I made a tool that you can decode and encode jwt and share them using streamlit

https://jwtjwt.streamlit.app/?embedded=True&_jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZXNvdXJjZSI6IlRoZSBBbnN3ZXIgdG8gdGhlIFVsdGltYXRlIFF1ZXN0aW9uIG9mIExpZmUsIHRoZSBVbml2ZXJzZSwgYW5kIEV2ZXJ5dGhpbmciLCJleHAiOjE2OTQ2OTczNTl9.vq9DpBxAAHGbW9rnRK7guo-IxPYJd16caFrk6RjydJc&expiration=60&resource=The+Answer+to+the+Ultimate+Question+of+Life%2C+the+Universe%2C+and+Everything&secret=42