Search code examples
djangoreactjsreduxdjango-rest-frameworkspotify

How to pass user back to front end client after authorizing and obtaining access token?


I have a Django backend and React/Redux front end and I am trying to integrate the Spotify API. I am a total django noob so please have mercy. I currently send the user to my backend via a regular ol' anchor tag on the front end. My backend then redirects the user to the Spotify Authorize page and then that page redirects them to another page which trades the authorization code for the access token which I now have. However this code and the urls just send me to my backend API. How do I get the user back to the front end with this access token? "My" code:

from django.views.generic.base import RedirectView, TemplateView
from rest_framework.response import Response
from rest_framework import generics, viewsets, permissions
from django.urls import reverse
from furl import furl
import requests


def build_authorize_url(request):
    params = {
        "client_id": "<client-id>",
        "response_type": "code",
        "redirect_uri": request.build_absolute_uri(
            reverse("spotify callback")
        ),
        "scope": " ".join(
            [
                'user-read-currently-playing',
                'user-modify-playback-state',
                'user-read-playback-state',
                'streaming',
                'app-remote-control',
                'playlist-read-collaborative',
                'playlist-modify-public',
                'playlist-read-private',
                'playlist-modify-private',
                'user-library-modify',
                'user-top-read',
                'user-read-playback-position',
                'user-read-recently-played',
            ]
        ),
    }
    print(params)

    url = (
        furl("https://accounts.spotify.com/authorize")
        .add(params)
        .url
    )
    print(url)

    return url


AUTH_HEADER = {
    "Authorization": "Basic "
    + base64.b64encode(
        "<my client id>:<my client secret>".encode()
    ).decode()
}


def handle_callback(request):
    code = request.GET["code"]

    response = requests.post(
        "https://accounts.spotify.com/api/token",
        data={
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": request.build_absolute_uri(
                reverse("spotify callback")
            ),
        },
        headers=AUTH_HEADER,
    )

    return response.json()


class SpotifyLoginView(RedirectView):
    query_string = True

    def get_redirect_url(self, *args, **kwargs):
        return build_authorize_url(self.request)


class SpotifyCallbackView(generics.GenericAPIView):
    def get(self, request, *args, **kwargs):
        print(handle_callback(request))

        return Response(handle_callback(request))


Solution

  • After getting the access/refresh token you can redirect the user to your frontend URL passing the token values like in this official example from Spotify's Github account (written in JS but the idea is the same):

    res.redirect('/#' +
      querystring.stringify({
        access_token: access_token,
        refresh_token: refresh_token
      })
    );
    

    You can read more about the authentication flows here.