Skip to content

Commit

Permalink
Changed the authentication type we're using to access the API
Browse files Browse the repository at this point in the history
This allows us to not need the secret, and just the ClientID.

Not sure how this is more secure, but apparently it is and it works so let's use it!
  • Loading branch information
Kieran Bond authored and KieranBond committed Jan 31, 2020
1 parent 24e2ae5 commit 323169f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 140 deletions.
155 changes: 48 additions & 107 deletions MiniSpotify/MiniSpotify/Source/APIRequestor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ public static APIRequestor Instance

private int m_songChangePollDelayMS = /*10000*/1000;//1 second

private string m_baseFilePath = "\\Assets\\Files\\URLPath.txt";
private string m_authFilePath = "\\Assets\\Files\\AuthorisePath.txt";
//private string m_tokenFilePath = "\\Assets\\Files\\AuthToken.txt";
private string m_baseURL = default;
private string m_authURL = default;

Expand All @@ -57,7 +54,6 @@ public static APIRequestor Instance
private string m_albumimage = "";

//https://developer.spotify.com/documentation/general/guides/scopes/
//private string m_accessScopes = "user-modify-playback-state";//These are seperated by %20's
private Scope m_accessScopes = Scope.UserModifyPlaybackState | Scope.Streaming | Scope.UserReadRecentlyPlayed | Scope.UserReadCurrentlyPlaying | Scope.UserReadPlaybackState | Scope.UserLibraryModify | Scope.UserLibraryRead;
private HttpClient m_webClient;
private static SpotifyWebAPI m_spotifyWebAPI;
Expand All @@ -67,23 +63,11 @@ public void Initialise()
{
m_instance = new APIRequestor();

string webBase = FileHelper.GetFileText(m_baseFilePath);
if (webBase != null && !string.IsNullOrEmpty(webBase))
{
m_instance.m_baseURL = webBase;
}

string authBase = FileHelper.GetFileText(m_authFilePath);
if (authBase != null && !string.IsNullOrEmpty(authBase))
{
m_instance.m_authURL = authBase;
}

string secret = FileHelper.GetFileText(m_clientSecretPath);
if (!string.IsNullOrEmpty(secret))
{
m_instance.m_clientSecret = secret;
}
//string secret = FileHelper.GetFileText(m_clientSecretPath);
//if (!string.IsNullOrEmpty(secret))
//{
// m_instance.m_clientSecret = secret;
//}

AuthAPI();
}
Expand All @@ -92,39 +76,63 @@ private async void AuthAPI()
{
//Source:
//https://github.com/JohnnyCrazy/SpotifyAPI-NET
//https://johnnycrazy.github.io/SpotifyAPI-NET/auth/implicit_grant.html

//If token isn't set, or has expired
if (m_instance.m_authToken == null || m_instance.m_authToken.IsExpired())
{
string redirectURI = "http://localhost:4002";

#region Old Auth method

//AuthorizationCodeAuth auth = new AuthorizationCodeAuth(
// m_instance.m_clientID,
// m_instance.m_clientSecret,
// redirectURI,
// redirectURI,
// m_accessScopes);

//auth.AuthReceived += async (sender, payload) =>
//{
// auth.Stop(); //Sender is also the auth instance

AuthorizationCodeAuth auth = new AuthorizationCodeAuth(
m_instance.m_clientID,
m_instance.m_clientSecret,
redirectURI,
redirectURI,
m_accessScopes);
// m_instance.m_authToken = await auth.ExchangeCode(payload.Code);

// m_spotifyWebAPI = new SpotifyWebAPI()
// {
// //TokenType = payload.TokenType,
// TokenType = m_instance.m_authToken.TokenType,
// //AccessToken = payload.AccessToken
// AccessToken = m_instance.m_authToken.AccessToken,
// UseAuth = true
// };

// m_instance.m_pollingTask = Task.Run(PollSongChange);//Start the song change polling

// m_instance.m_onAuthComplete.Invoke(GetLatestTrack());
//};
#endregion

ImplicitGrantAuth auth = new ImplicitGrantAuth(
m_instance.m_clientID,
redirectURI,
redirectURI,
m_accessScopes);

auth.AuthReceived += async (sender, payload) =>
{
auth.Stop(); //Sender is also the auth instance
m_instance.m_authToken = await auth.ExchangeCode(payload.Code);
auth.Stop(); // `sender` is also the auth instance
m_instance.m_authToken = payload;
m_spotifyWebAPI = new SpotifyWebAPI()
{
//TokenType = payload.TokenType,
TokenType = m_instance.m_authToken.TokenType,
//AccessToken = payload.AccessToken
AccessToken = m_instance.m_authToken.AccessToken,
UseAuth = true
};
m_instance.m_pollingTask = Task.Run(PollSongChange);//Start the song change polling
m_instance.m_onAuthComplete.Invoke(GetLatestTrack());
};

auth.Start();//Starts an internal http server
Expand All @@ -147,9 +155,11 @@ public void Close()
m_pollingTask = null;
}

m_spotifyWebAPI.Dispose();
m_spotifyWebAPI = null;

if(m_spotifyWebAPI != null)
{
m_spotifyWebAPI.Dispose();
m_spotifyWebAPI = null;
}

}

Expand Down Expand Up @@ -465,74 +475,5 @@ private async void PollSongChange()
await Task.Delay(m_songChangePollDelayMS);
}
}

#region Our own API implement - Not using until fully functional.

public async Task<string> Request(string a_reqPath, REST a_type = REST.GET)
{
string rest = FileHelper.GetRestString(a_type);
// dispose it when done, so the app doesn't leak resources
using (m_instance.m_webClient)
{
string uri = rest + "" + m_baseURL + "/" + a_reqPath;
// Call asynchronous network methods in a try/catch block to handle exceptions
try
{
return await m_instance.m_webClient.GetStringAsync(uri);
}
catch (HttpRequestException e)
{
Console.WriteLine("\nFailed to load request");
Console.WriteLine("Message :{0} ", e.Message);
return null;
}
}
}


//My one.. Might work now if we use local host, but using the github lib instead for now
private async void Authenticate()
{
//https://developers.google.com/identity/protocols/OAuth2InstalledApp
//https://github.com/googlesamples/oauth-apps-for-windows/blob/master/OAuthDesktopApp/OAuthDesktopApp/

// Creates a redirect URI using an available port on the loopback address.
//string redirectURI = string.Format("http://{0}/{1}/", "kieranbond.github.io", "minispotify"); //string redirectURI = string.Format("http://{0}/{1}/", "kieranbond.github.io", "minispotify");
string redirectURI = "http://www.kieranbond.co.uk/minispotify/";
//string redirectURI = string.Format("http://{0}:{1}", IPAddress.Loopback, GetRandomUnusedPort());
string rest = FileHelper.GetRestString(REST.GET);

// Creates an HttpListener to listen for requests on that redirect URI.
HttpListener redirectListener = new HttpListener();
redirectListener.Prefixes.Add(redirectURI);
redirectListener.Start();
//We need to be running in Admin mode for this request
//to work - Otherwise we get an exception.
//https://stackoverflow.com/questions/4019466/httplistener-access-denied

string requestURI = string.Format("{0}?client_id={1}&response_type=code&" +
"redirect_uri={2}&scope={3}", m_authURL, m_clientID, redirectURI, m_accessScopes);
string restedRequestURI = rest + " " + requestURI;

// Opens request in the browser.
Process.Start(requestURI);

// Waits for the OAuth authorization response.
var context = await redirectListener.GetContextAsync();
string code = context.Request.QueryString.Get("code");
Console.WriteLine("Code: " + code);
redirectListener.Stop();
//var response = context.Response;
//var responseStream = response.OutputStream;
//Task responseTask = responseStream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
//{
// responseStream.Close();
// redirectListener.Stop();
// Console.WriteLine("HTTP server stopped.");
//});

}

#endregion
}
}
23 changes: 0 additions & 23 deletions MiniSpotify/MiniSpotify/Source/Helpers/FileHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,6 @@ namespace MiniSpotify.HelperScripts
{
public static class FileHelper
{
public static string GetRestString(REST a_type)
{
switch (a_type)
{
case REST.GET:

return "GET";
case REST.POST:

return "POST";

case REST.PUT:

return "PUT";

case REST.DELETE:

return "DELETE";
}

return null;//Else
}

public static string GetFileText(string a_filePath)
{
//string path = Path.Combine(Environment.CurrentDirectory, a_filePath);
Expand Down
10 changes: 0 additions & 10 deletions MiniSpotify/MiniSpotify/Source/Interfaces/IAPIRequestor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,7 @@ namespace MiniSpotify.API.Base
{
public interface IAPIRequestor
{

void Initialise();
void Close();

Task<string> Request(string a_reqPath, REST a_type = REST.GET);
}
public enum REST
{
GET,
POST,
PUT,
DELETE
};
}

0 comments on commit 323169f

Please sign in to comment.