WFP C# 应用中的 Spotify OAuth - 无法完成身份验证过程

Spotify OAuth in WFP C# app - cannot complete authentication process

提问人:nzmike 提问时间:10/27/2023 更新时间:10/27/2023 访问量:26

问:

我正在尝试扩展我用来搜索 Spotify 的现有 WPF 应用程序,以便我可以根据我不再使用的音乐应用程序中的一大堆 M3U 播放列表文件在我的帐户中添加新的播放列表。(我知道有免费的工具可以做到这一点,但它们大多是无用的,所以我想推出自己的工具,因为我有额外的匹配逻辑想要应用)。

因此,我正在使用 Github 的 SpotifyAPI-Net 并获得 PKCE 授权,并根据此页面实现了我认为应该工作的内容:https://johnnycrazy.github.io/SpotifyAPI-NET/docs/pkce

目前,我的代码正在执行以下操作:

  1. 启动 HttpListener 以侦听 http://localhost:5543/callback/ 加载窗口。(此 URL 已在 Spotify 仪表板中指定,这是回调工作所需的。

     private const string CallbackURL = "http://localhost:5543/callback/";  
    
     private void Window_Loaded(object sender, RoutedEventArgs e)
     {
         //If we do a plain Await here it blocks the UI from running
         Task.Run(() => StartServer());
     }
    
         public async Task StartServer()
         {
             //Set up listener for callback on http://localhost:5543/callback/
             HttpListener listener = new HttpListener();
             listener.Prefixes.Add(CallbackURL );  
             listener.Start();
             while (true)
             {
                 var context = listener.GetContext();
                 if (context != null)
                 {
                     authCode = context.Request.QueryString["code"];
                     await GetCallback(authCode);
                     break;
                 }
             }
             listener.Stop();
         }
    
  2. 然后,我使用身份验证请求生成Spotify loginURL,如下所示:

     public void BuildSpotifyAuthURL()
     {
         // Generates a secure random verifier of length 100 and its challenge
         var (verifier, challenge) = PKCEUtil.GenerateCodes();
    
         var loginRequest = new LoginRequest(
           new Uri(CallbackURL),
           SPOTIFYUTIL_CLIENT_ID,
           LoginRequest.ResponseType.Code
         )
         {
             CodeChallengeMethod = "S256",
             CodeChallenge = challenge,
             Scope = new[] { Scopes.PlaylistReadPrivate, Scopes.PlaylistReadCollaborative }
         };
         LoginUri = loginRequest.ToUri();
    
         Process.Start(LoginUri.ToString());
     }
    

这给了我一个这样的 URL:https://accounts.spotify.com/authorize?client_id=&response_type=code&redirect_uri=http%3a%2f%2flocalhost%3a5543%2fcallback%2f&scope=playlist-read-private+playlist-read-collaborative&code_challenge=Fc-GVHr1dzlLMPwuQw0e4Ex3c1w8xv5c5rNym-N6tPU&code_challenge_method=S256

由于这是一个 WPF 应用程序,因此我运行 Process.Start() 以在默认浏览器 (Firefox) 中打开 URL。然后它向我显示要求我同意使用条款的页面,所以我单击“同意”,侦听器按预期触发,我看到一个类似“http://localhost:5543/callback/?code=”的 URL(也符合预期),但是当下面的 GetCallback 方法触发时,它永远不会超过“await new OAuthClient(...)”行 - 即:它没有到达我尝试创建 SpotifyClient 的下一行。

    public async Task GetCallback(string code)
    {
        var (verifier, challenge) = PKCEUtil.GenerateCodes();
        var initialResponse = await new OAuthClient().RequestToken(
                new PKCETokenRequest(SPOTIFYUTIL_CLIENT_ID, code, new System.Uri(CallbackURL), verifier)  
        );
   
        //Code never gets here but this is the same as the example code on the GitLab website... guessing await above is returning the Task immediately
        spotifyClient = new SpotifyClient(initialResponse.AccessToken);
        var user = spotifyClient.UserProfile.Current();
        txtPLTestOutput.Text = user.Result.DisplayName;
    }

因此,从调试中,我可以看到它返回的 Task 实例,但问题是,即使我将“initialResponse”设置为全局变量,它也永远不会获得值,因此即使我尝试在其他地方执行最后三行(例如在另一个 Button 事件处理程序或方法中),它也显示为 null。

我认为这是一个aysnc问题,而不是OAuth问题,但我不确定我打算如何存储PKCETokenResponse的实例,以便它可以用来创建SpotifyClient的实例。

在过去的几年里,我没有做过太多的 C#,所以如果有人能指出我可能出错的地方,我将不胜感激,我已经尝试了几个小时来修复它,但没有运气。

wpf async-await oauth 回调 spotify

评论


答: 暂无答案