Flask - скопировать текущий контекст запроса - PullRequest
1 голос
/ 21 марта 2020

В моем приложении я использую поток кода авторизации для Spotify.

Вот конечная точка обратного вызова авторизации, где я получаю токены от Spotify.


spotify_auth.py

from flask import Blueprint
from flask import Flask, request, session, redirect

spotify_auth_bp = Blueprint('spotify_auth', 
                    __name__, 
                    template_folder='templates',
                    static_url_path='static') 

@spotify_auth_bp.route("/callback", methods=['GET', 'POST'])
def spotify_callback():

    SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"

    CLIENT_ID =   os.environ.get('SPOTIPY_CLIENT_ID')
    CLIENT_SECRET = os.environ.get('SPOTIPY_CLIENT_SECRET')
    REDIRECT_URI = os.environ.get('SPOTIPY_REDIRECT_URI')

    auth_token = request.args['code']

    code_payload = {
        "grant_type": "authorization_code",
        "code": auth_token,
        "redirect_uri": REDIRECT_URI,
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
    }

    post_request = requests.post(SPOTIFY_TOKEN_URL, data=code_payload)

    response_data = json.loads(post_request.text)

    access_token = response_data["access_token"]
    refresh_token = response_data["refresh_token"]
    token_type = response_data["token_type"]
    expires_in = response_data["expires_in"]

   # At this point, there is to generate a custom token for the frontend
   # Either a self-contained signed JWT or a random token
   # In case the token is not a JWT, it should be stored in the session (in case of a stateful API)
   # or in the database (in case of a stateless API)
   # In case of a JWT, the authenticity can be tested by the backend with the signature so it doesn't need to be stored at all
   # Let's assume the resulting token is stored in a variable named "token"

res = Response('http://localhost/about', status=302)
res.set_cookie('auth_cookie', token)
return res

Теперь у меня есть эти функции для обработки моего доступа и обновления sh токенов:

def refresh_access_token():
    SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"

    code_payload = {
        "grant_type": "refresh_token",
        "refresh_token": refresh_token,
    }

    encode = 'application/x-www-form-urlencoded'
    auth = base64.b64encode("{}:{}".format(client_id, client_secret).encode())
    headers = {"Content-Type" : encode, "Authorization" : "Basic {}".format(auth)} 

    post_request = requests.post(SPOTIFY_TOKEN_URL, data=code_payload, headers=headers)
    response_data = json.loads(post_request.text)

    access_token = response_data["access_token"]
    refresh_token = response_data["refresh_token"]
    token_type = response_data["token_type"]
    expires_in = response_data["expires_in"]

    # save new tokens to database
    user = User.query.filter_by(refresh_token=refresh_token).first()
    user.access_token = access_token
    user.refresh_token = refresh_token
    db.session.commit()

    return access_token



def get_token():
    # check for cookies 
    access_token_cookie = request.cookies.get('access_token')
    refresh_token_cookie = request.cookies.get('refresh_token')

    # check if this is first User login
    user = User.query.filter_by(access_token=access_token_cookie).first()
    if user:
        # Checking if token has expired
        now = int(time.time())
        token_is_expired = request.cookies.get('expires_in') - now < 60
         # Refreshing token if it has expired
        if token_is_expired:
            # get token for renewal from db
            refresh_token = user.refresh_token
            # request another access token
            access_token = refresh_access_token(refresh_token)
        else:
            access_token = user.access_token
    else:
        # first time user
        user = User.query.filter_by(id=1).first()

        user.access_token_cookie = access_token_cookie
        user.refresh_token = refresh_token_cookie
        db.session.commit()

        access_token = access_token_cookie

    return access_token

В идеале я хотел бы импортировать эти функции в мои модули и передавать токен своим ресурсам просто с помощью:

spotify_utils.py

import get_token

token =  get_token()

Как поместить эти функции в контекст?


Я узнал, что copy_current_request_context может помочь мне в этом.

Есть идеи?

...