2015-11-30 36 views
5

Próbuję wywołać API spotify z C#. Niestety, mam już skazani na uzyskanie access tokenJak wywołać API Spotify z C#

ten sposób starałem się go:

private static async Task<string> GetAccessToken() 
     { 
      SpotifyToken token = new SpotifyToken(); 

      string postString = string.Format("grant_type=client_credentials"); 
      byte[] byteArray = Encoding.UTF8.GetBytes(postString); 

      string url = "https://accounts.spotify.com/api/token"; 

      WebRequest request = WebRequest.Create(url); 
      request.Method = "POST"; 
      request.Headers.Add("Authorization", "Basic {Encoded myClientIdXXX:myAppSecretYYY}"); 
      request.ContentType = "application/x-www-form-urlencoded"; 
      request.ContentLength = byteArray.Length; 
      using (Stream dataStream = request.GetRequestStream()) 
      { 
       dataStream.Write(byteArray, 0, byteArray.Length); 
       using (WebResponse response = await request.GetResponseAsync()) 
       { 
        using (Stream responseStream = response.GetResponseStream()) 
        { 
         using (StreamReader reader = new StreamReader(responseStream)) 
         { 
          string responseFromServer = reader.ReadToEnd(); 
          token = JsonConvert.DeserializeObject<SpotifyToken>(responseFromServer); 
         } 
        } 
       } 
      } 
      return token.access_token; 
     } 

ale pojawia się błąd:

Der Remoteserver hat einen Fehler zurückgegeben: (400) Ungültige Anforderung.

co przekłada się na:

The remote server returned an error: (400) Bad Request.

Co ja tu robię źle? Mam zarejestrowany na moją aplikację Spotify i ustawić ClientID i tajemnica w nagłówku żądania ...

góry dzięki

+0

English please! –

+0

* Serwer zdalny zwrócił błąd: (400) Złe żądanie. –

+0

Dzięki Taegost i @SethKitchen za dodanie angielskiego tłumaczenia komunikatu o błędzie – Harry

Odpowiedz

5

Czy naprawdę trzeba napisać własny klienta od podstaw WebRequests budowlanych, itp? Dlaczego nie skorzystać z istniejącego klienta, takiego jak SpotifyAPI-NET?

W każdym razie, można zobaczyć, jak oni to robią, na GitHub:

https://github.com/JohnnyCrazy/SpotifyAPI-NET/blob/master/SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs

using Newtonsoft.Json; 
using SpotifyAPI.Web.Enums; 
using SpotifyAPI.Web.Models; 
using System; 
using System.Collections.Specialized; 
using System.Diagnostics; 
using System.IO; 
using System.Net; 
using System.Text; 
using System.Threading; 

namespace SpotifyAPI.Web.Auth 
{ 
    public class AutorizationCodeAuth 
    { 
     public delegate void OnResponseReceived(AutorizationCodeAuthResponse response); 

     private SimpleHttpServer _httpServer; 
     private Thread _httpThread; 
     public String ClientId { get; set; } 
     public String RedirectUri { get; set; } 
     public String State { get; set; } 
     public Scope Scope { get; set; } 
     public Boolean ShowDialog { get; set; } 

     /// <summary> 
     ///  Will be fired once the user authenticated 
     /// </summary> 
     public event OnResponseReceived OnResponseReceivedEvent; 

     /// <summary> 
     ///  Start the auth process (Make sure the internal HTTP-Server ist started) 
     /// </summary> 
     public void DoAuth() 
     { 
      String uri = GetUri(); 
      Process.Start(uri); 
     } 

     /// <summary> 
     ///  Refreshes auth by providing the clientsecret (Don't use this if you're on a client) 
     /// </summary> 
     /// <param name="refreshToken">The refresh-token of the earlier gathered token</param> 
     /// <param name="clientSecret">Your Client-Secret, don't provide it if this is running on a client!</param> 
     public Token RefreshToken(string refreshToken, string clientSecret) 
     { 
      using (WebClient wc = new WebClient()) 
      { 
       wc.Proxy = null; 
       wc.Headers.Add("Authorization", 
        "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + clientSecret))); 
       NameValueCollection col = new NameValueCollection 
       { 
        {"grant_type", "refresh_token"}, 
        {"refresh_token", refreshToken} 
       }; 

       String response; 
       try 
       { 
        byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col); 
        response = Encoding.UTF8.GetString(data); 
       } 
       catch (WebException e) 
       { 
        using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) 
        { 
         response = reader.ReadToEnd(); 
        } 
       } 
       return JsonConvert.DeserializeObject<Token>(response); 
      } 
     } 

     private String GetUri() 
     { 
      StringBuilder builder = new StringBuilder("https://accounts.spotify.com/authorize/?"); 
      builder.Append("client_id=" + ClientId); 
      builder.Append("&response_type=code"); 
      builder.Append("&redirect_uri=" + RedirectUri); 
      builder.Append("&state=" + State); 
      builder.Append("&scope=" + Scope.GetStringAttribute(" ")); 
      builder.Append("&show_dialog=" + ShowDialog); 
      return builder.ToString(); 
     } 

     /// <summary> 
     ///  Start the internal HTTP-Server 
     /// </summary> 
     public void StartHttpServer(int port = 80) 
     { 
      _httpServer = new SimpleHttpServer(port, AuthType.Authorization); 
      _httpServer.OnAuth += HttpServerOnOnAuth; 

      _httpThread = new Thread(_httpServer.Listen); 
      _httpThread.Start(); 
     } 

     private void HttpServerOnOnAuth(AuthEventArgs e) 
     { 
      OnResponseReceivedEvent?.Invoke(new AutorizationCodeAuthResponse() 
      { 
       Code = e.Code, 
       State = e.State, 
       Error = e.Error 
      }); 
     } 

     /// <summary> 
     ///  This will stop the internal HTTP-Server (Should be called after you got the Token) 
     /// </summary> 
     public void StopHttpServer() 
     { 
      _httpServer = null; 
     } 

     /// <summary> 
     ///  Exchange a code for a Token (Don't use this if you're on a client) 
     /// </summary> 
     /// <param name="code">The gathered code from the response</param> 
     /// <param name="clientSecret">Your Client-Secret, don't provide it if this is running on a client!</param> 
     /// <returns></returns> 
     public Token ExchangeAuthCode(String code, String clientSecret) 
     { 
      using (WebClient wc = new WebClient()) 
      { 
       wc.Proxy = null; 

       NameValueCollection col = new NameValueCollection 
       { 
        {"grant_type", "authorization_code"}, 
        {"code", code}, 
        {"redirect_uri", RedirectUri}, 
        {"client_id", ClientId}, 
        {"client_secret", clientSecret} 
       }; 

       String response; 
       try 
       { 
        byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col); 
        response = Encoding.UTF8.GetString(data); 
       } 
       catch (WebException e) 
       { 
        using (StreamReader reader = new StreamReader(e.Response.GetResponseStream())) 
        { 
         response = reader.ReadToEnd(); 
        } 
       } 
       return JsonConvert.DeserializeObject<Token>(response); 
      } 
     } 
    } 

    public struct AutorizationCodeAuthResponse 
    { 
     public String Code { get; set; } 
     public String State { get; set; } 
     public String Error { get; set; } 
    } 
} 
+0

Próbowałem go użyć, ale nie można dodać pakietu Nuget do projektu, który jest kierowany do dowolnej z najnowszych wersji systemu Windows 10. Co właściwie chcę do jest stworzenie aplikacji Xamarin, ale nie może znaleźć nic, co może dać mi nogi w autoryzacji Spotify z pcl. Ktoś ma jakieś pomysły? – BGTurner

0

Wystarczy zakodować swoją aplikację ClientID i ClientSecret:

var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}",this.CliendId,this.ClientSecret))); 

Wymienić odpowiednio:

request.Headers.Add("Authorization", "Basic " + token); 

To wszystko!

0

Spotify API z C#

public string GetAccessToken() 
    { 
      SpotifyToken token = new SpotifyToken(); 
      string url5 = "https://accounts.spotify.com/api/token"; 
      var clientid = "your_client_id"; 
      var clientsecret = "your_client_secret"; 

      //request to get the access token 
      var encode_clientid_clientsecret = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", clientid, clientsecret))); 

      HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url5); 

      webRequest.Method = "POST"; 
      webRequest.ContentType = "application/x-www-form-urlencoded"; 
      webRequest.Accept = "application/json"; 
      webRequest.Headers.Add("Authorization: Basic " + encode_clientid_clientsecret); 

      var request = ("grant_type=client_credentials"); 
      byte[] req_bytes = Encoding.ASCII.GetBytes(request); 
      webRequest.ContentLength = req_bytes.Length; 

      Stream strm = webRequest.GetRequestStream(); 
      strm.Write(req_bytes, 0, req_bytes.Length); 
      strm.Close(); 

      HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse(); 
      String json = ""; 
      using (Stream respStr = resp.GetResponseStream()) 
      { 
       using (StreamReader rdr = new StreamReader(respStr, Encoding.UTF8)) 
       { 
        //should get back a string i can then turn to json and parse for accesstoken 
        json = rdr.ReadToEnd(); 
        rdr.Close(); 
       } 
      } 
    return token.access_token; 
} 
+0

To jest to, czego potrzebowałem. Dzięki! –