Authentication not working in a live server | Spotipy

Viewed 38

I am using Django and when I run a local server at localhost:8000, this piece of code works as intended:

        spotipy.Spotify(
            auth_manager=SpotifyOAuth(
                redirect_uri=config["REDIRECT_URI"],
                client_id=config["SPOTIPY_CLIENT_ID"],
                client_secret=config["SPOTIPY_CLIENT_SECRET"],
                scope="user-library-read user-library-modify playlist-modify-private playlist-modify-public",
                cache_handler=spotipy.DjangoSessionCacheHandler(request),
            )
        ).current_user()

It redirects me to http://localhost:8080/callback and fetches all the data by itself and caches the received token. But when I do the same on a live server, it doesn't redirect me and the bash asks me to input the URL I have been redirected to. enter image description here

I even tried including a false redirect_uri but it still asks me for the URL I have been redirected to. I have no idea what I am doing wrong, any help is appreciated.

1 Answers

Turns out that piece of code is not how I should be doing the authentication, this should be used instead:

In middleware.py: (make the file yourself in your app)

# This will run every time before the view is loaded
# Make sure you enable this middleware in your settings.py
def is_user_authenticated(get_response):
    # Initialize request.code because we'll be using that in the index function in views.py
    def middleware(request):
        request.code = None
        if "authenticate" not in request.path:
            # If the current path is not /authenticate then we run this

            # In the function authenticate in views.py, we passed context["auth_url"] to
            # the html so the user can press the link and get sent to the spotify
            # authentication page, once they accept/refuse they will get redirected back
            # to / that the index function handles, but before that happens we must
            # capture the code that the authentication link gave us and put it in request.code
            if request.method == "GET" and request.GET.get("code"):
                request.code = request.GET.get("code")

            # This ensures that the token is valid aka not expired when every view loads
            if not request.code:
                cache_handler = spotipy.DjangoSessionCacheHandler(request)
                auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
                if not auth_manager.validate_token(cache_handler.get_cached_token()):
                    return redirect("/authenticate")

        response = get_response(request)
        return response

    return middleware

In views.py:

# url to this view is /
def index(request):

    # If request.code exists, then we are set and we can authenticate the user
    if request.code:
        cache_handler = spotipy.DjangoSessionCacheHandler(request)
        auth_manager = spotipy.oauth2.SpotifyOAuth(
            scope="user-library-read",
            cache_handler=cache_handler,
            show_dialog=True,
        )
        auth_manager.get_access_token(request.code)
        return redirect("/home")

    # Else, redirect them to authenticate
    return redirect("/authenticate")

# url to this view is authenticate/
def authenticate(request):
    context = {}
    cache_handler = spotipy.DjangoSessionCacheHandler(request)
    auth_manager = spotipy.oauth2.SpotifyOAuth(cache_handler=cache_handler)
    if auth_manager.validate_token(cache_handler.get_cached_token()):
        # If token already exists and is valid, redirect them to the home page
        return redirect("/home")

    # Make sure your client_id/client_secret/redirect_uri environment variables are set
    auth_manager = spotipy.oauth2.SpotifyOAuth(
        scope="user-library-read",
        cache_handler=cache_handler,
        show_dialog=True,
    )

    # In authenticate page there is a link button with href set to context["auth_url"]
    context["auth_url"] = auth_manager.get_authorize_url()

    return render(request, "authenticate.html", context)

I got the code flow from a flask app example in the official github: https://github.com/plamere/spotipy/blob/master/examples/app.py

Related