Need to see if your shared folder is taking up space on your dropbox 👨💻? Find out how to check here.
Forum Discussion
Shy1
4 years agoExplorer | Level 3
It must exactly match one of the redirect URIs you've pre-configured for your app (including the pat
I'm completely confused. I do it according to the documentation,
if I make a link with my hands in my browser and insert the AppiKey, then everything works,
if I try to do it through the code, I get this Invalid redirect_uri message.
It must exactly match one of the redirect URIs you've pre-configured for your app (including the path). In console I added redirect url just like in code private const string LoopbackHost = "http://127.0.0.1:4200/"; what is my problem
// Add an ApiKey (from https://www.dropbox.com/developers/apps) here
private const string ApiKey = "XXX";
// This loopback host is for demo purpose. If this port is not
// available on your machine you need to update this URL with an unused port.
private const string LoopbackHost = "http://127.0.0.1:4200/";
// URL to receive OAuth 2 redirect from Dropbox server.
// You also need to register this redirect URL on https://www.dropbox.com/developers/apps.
private readonly Uri RedirectUri = new Uri(LoopbackHost + "authorize");
// URL to receive access token from JS.
private readonly Uri JSRedirectUri = new Uri(LoopbackHost + "token");
public async void MainRun()
{
var accessToken = await this.GetAccessToken();
}
private async Task<string> GetAccessToken()
{
var accessToken = string.Empty;
if (string.IsNullOrEmpty(accessToken))
{
try
{
Console.WriteLine("Waiting for credentials.");
var state = Guid.NewGuid().ToString("N");
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, ApiKey, RedirectUri, state: state);
var http = new HttpListener();
http.Prefixes.Add(LoopbackHost);
http.Start();
Console.WriteLine(1);
//Process.Start("C:\\Program Files\\Internet Explorer\\IExplore.exe", authorizeUri.ToString());
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
string url = authorizeUri.ToString().Replace("&", "^&");
Process.Start(new ProcessStartInfo("cmd", $"/c start {url}"));//{ CreateNoWindow = true }
//Console.WriteLine(url);
}
else
{
Process.Start(authorizeUri.ToString());
}
// Handle OAuth redirect and send URL fragment to local server using JS.
await HandleOAuth2Redirect(http);
Console.WriteLine(2);
// Handle redirect from JS and process OAuth response.
var result = await HandleJSRedirect(http);
Console.WriteLine(3);
if (result.State != state)
{
// The state in the response doesn't match the state in the request.
return null;
}
Console.WriteLine("and back...");
accessToken = result.AccessToken;
var uid = result.Uid;
Console.WriteLine("Uid: {0}", uid);
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e.Message);
return null;
}
}
return accessToken;
}
private async Task HandleOAuth2Redirect(HttpListener http)
{
var context = await http.GetContextAsync();
// We only care about request to RedirectUri endpoint.
while (context.Request.Url.AbsolutePath != RedirectUri.AbsolutePath)
{
context = await http.GetContextAsync();
}
context.Response.ContentType = "text/html";
// Respond with a page which runs JS and sends URL fragment as query string
// to TokenRedirectUri.
using (var file = File.OpenRead("index.html"))
{
file.CopyTo(context.Response.OutputStream);
}
context.Response.OutputStream.Close();
}
/// <summary>
/// Handle the redirect from JS and process raw redirect URI with fragment to
/// complete the authorization flow.
/// </summary>
/// <param name="http">The http listener.</param>
/// <returns>The <see cref="OAuth2Response"/></returns>
private async Task<OAuth2Response> HandleJSRedirect(HttpListener http)
{
var context = await http.GetContextAsync();
// We only care about request to TokenRedirectUri endpoint.
while (context.Request.Url.AbsolutePath != JSRedirectUri.AbsolutePath)
{
context = await http.GetContextAsync();
}
var redirectUri = new Uri(context.Request.QueryString["url_with_fragment"]);
var result = DropboxOAuth2Helper.ParseTokenFragment(redirectUri);
return result;
}
12 Replies
Replies have been turned off for this discussion
- Здравко4 years agoLegendary | Level 20
Shy1 wrote:
...
if I try to do it through the code, I get this Invalid redirect_uri message.
It must exactly match one of the redirect URIs you've pre-configured for your app (including the path). In console I added redirect url just like in code private const string LoopbackHost = "http://127.0.0.1:4200/"; what is my problem...
Hi Shy1,
To be honest, I'm not certain what exactly you're asking for (the question contains response within). I will speculate that you cannot understand difference between terms URI and host (domain name) and that's why you mix them. Your LoopbackHost keeps the host (represented as IP 127.0.0.1 - i.e. loopback IP) as part of URL used as a base for further construction of final redirect URI (here it's URL actually). On registration, complete URL have to be used without possible parameters (anchor isn't used at all). The parameters will be added on redirection and you should process them in your code. 😉 Hope now it's a bit more clear. Take a look here for more info related to URL anatomy (URI can be considered as a URL generalization, but in your case they mean the same thing in fact). 😁 How looks like the redirect URI in your code and is it registered appropriately? 🧐🙂 If you are still not sure, what appears in your browser address bar on redirection (and before that) and after remove parameters is it the same as the registered URI? Is your browser launched with the same URL when you make it by hands and through the code? Why?
Hope this gives direction and clarifies matter.
In addition, you can read the comments in your code:
Shy1 wrote:...
... // URL to receive OAuth 2 redirect from Dropbox server. // You also need to register this redirect URL on https://www.dropbox.com/developers/apps. private readonly Uri RedirectUri = new Uri(LoopbackHost + "authorize"); ......
Does the above advice (need to register this redirect URL on) take proper attention? 🤔
- Shy14 years agoExplorer | Level 3
i am just delete anchor and error disapear. but i am still cant redirect to my 127.0.01 i suppose at my configuration pc problem? but at the browser url i have request
- Здравко4 years agoLegendary | Level 20
Shy1 wrote:i am just delete anchor and error disapear. ...
Shy1, Hmm.. 🤔 How have you deleted something nonexistent? I can see some anchor in your code responsible for redirect URI construction! I'm not sure you have some "configuration pc problem", but most probably you are mixing anchor and resource path. 🙂
Shy1 wrote:... but at the browser url i have request
Probably you mean the "redirect_uri" parameter there. Is the parameter value registered in the form it appears without your "correction"? 😉
Let me guess what's there. At the beginning you have a constant:
private const string LoopbackHost = "http://127.0.0.1:4200/";
The 'LoopbackHost's value is clear, as you noted it's "http://127.0.0.1:4200/". Let's see the next value:
// You also need to register this redirect URL on https://www.dropbox.com/developers/apps. private readonly Uri RedirectUri = new Uri(LoopbackHost + "authorize");Now we have previous value concatenated with "authorize" (i.e. 'RedirectUri's value is "http://127.0.0.1:4200/authorize"). 😉 Is that what appear? And as noted (in the comment), had you registered it? 🧐
About how your PC handle it, take a look here:
while (context.Request.Url.AbsolutePath != RedirectUri.AbsolutePath)
You code waits for the same 'RedirectUri's value and ignore everything else (keeps looping) until appearing. Can this even happen in your case? (your PC receives this value "corrected" by your hand!!!)
- Shy24 years agoNew member | Level 2
yes, I have it registered, because I can read. I get a response from the correct link, but my bowser gets the following error and the code exits without any exceptions, it just dies out. if I go through the debugger then I get to the HandleJSRedirect and everything ends there and if not through the debugger, then it ends on the process call Process.Start(); I do not understand anything
ERR_CONNECTION_REFUSED link what i have but i cant work with her and link down
maybe it's how i run it?
static void Main(string[] args) { Program program = new Program(); var task = Task.Run(program.MainRun); task.Wait(); } public async void MainRun() { var accessToken = await this.GetAccessToken(); } - Здравко4 years agoLegendary | Level 20
Shy2 wrote:... if I go through the debugger then I get to the HandleJSRedirect and everything ends there ...
On the previous call (call to 'HandleOAuth2Redirect') you have to send back to the browser a 'index.html' file (actually almost entire javascript content), responsible for additional redirection that seems missing. Are you sure correct content got the way? 🧐 You usually can debug/check this using the embedded browser tools (trace the communication). After the second redirect your browser should get redirected to something like:
http://127.0.0.1:4200/token?url_with_fragment=...Does this happen?
- Shy14 years agoExplorer | Level 3
if I take an example from github, and just change the AppKey and AppSecret and set my port, then everything goes fine and I get the following error: an error occurred while sending the request at the moment Exchanging code for token
- Здравко4 years agoLegendary | Level 20
Shy1 wrote:...
... // Respond with a page which runs JS and sends URL fragment as query string // to TokenRedirectUri. using (var file = File.OpenRead("index.html")) { file.CopyTo(context.Response.OutputStream); } ...Ok, let's take a look on above part of your code. Do you understand what exactly this code does and is the file "index.html" available?
- Shy14 years agoExplorer | Level 3
if I take an example from github, and just change the AppKey and AppSecret and set my port, then everything goes fine and I get the following error: an error occurred while sending the request at the moment Exchanging code for token
index.html at the project
<html> <script type="text/javascript"> function redirect() { // Append fragment as query string so that server can receive it. document.location.href = "/token?url_with_fragment=" + encodeURIComponent(document.location.href); } </script> <body onload="redirect()"/> </html>at this moment
var tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(redirectUri, ApiKey, ApiSecret, RedirectUri.ToString(), state); - Здравко4 years agoLegendary | Level 20
Shy1 wrote:... and I get the following error: an error occurred while sending the request at the moment Exchanging code for token ...
Are you sure you keep talking for the same thing? 🤔 I cannot find any place in your source code where you receive a authorization code (you're receiving access token only). In this context what actually you're trying to exchange??? 🧐
- Shy14 years agoExplorer | Level 3
I'm sorry, here is the code taken from the official dropbox source. I just tried to figure it out by pulling it into an empty project in parts, but when I gave up. turned to the original source, replacing the data with his own
namespace OauthTest { using System; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Runtime.InteropServices; using System.Threading.Tasks; using Dropbox.Api; partial class Program { // Add an ApiKey (from https://www.dropbox.com/developers/apps) here private const string ApiKey = "---"; // Add an ApiSecret (from https://www.dropbox.com/developers/apps) here private const string ApiSecret = "---"; // This loopback host is for demo purpose. If this port is not // available on your machine you need to update this URL with an unused port. private const string LoopbackHost = "http://127.0.0.1:4200/"; //deffault version 52475 my 4200 // URL to receive OAuth 2 redirect from Dropbox server. // You also need to register this redirect URL on https://www.dropbox.com/developers/apps. private readonly Uri RedirectUri = new Uri(LoopbackHost + "authorize"); // URL to receive access token from JS. private readonly Uri JSRedirectUri = new Uri(LoopbackHost + "token"); [DllImport("kernel32.dll", ExactSpelling = true)] private static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); [STAThread] static int Main(string[] args) { var instance = new Program(); try { Console.WriteLine("Example OAuth Application"); var task = Task.Run((Func<Task<int>>)instance.Run); task.Wait(); return task.Result; } catch (Exception e) { Console.WriteLine(e); throw e; } } private async Task<int> Run() { DropboxCertHelper.InitializeCertPinning(); string[] scopeList = new string[3] { "files.metadata.read", "files.content.read", "account_info.read" }; var uid = await this.AcquireAccessToken(scopeList, IncludeGrantedScopes.None); if (string.IsNullOrEmpty(uid)) { return 1; } // Specify socket level timeout which decides maximum waiting time when no bytes are // received by the socket. var httpClient = new HttpClient(new WebRequestHandler { ReadWriteTimeout = 10 * 1000 }) { // Specify request level timeout which decides maximum time that can be spent on // download/upload files. Timeout = TimeSpan.FromMinutes(20) }; try { var config = new DropboxClientConfig("SimpleOAuthApp") { HttpClient = httpClient }; var client = new DropboxClient(Settings.Default.AccessToken, Settings.Default.RefreshToken, ApiKey, ApiSecret, config); // This call should succeed since the correct scope has been acquired await GetCurrentAccount(client); Console.WriteLine("Refreshing without scope account_info.read"); var newScopes = new string[] { "files.metadata.read", "files.content.read" }; await client.RefreshAccessToken(newScopes); try { // This should fail since token does not have "account_info.read" scope await GetCurrentAccount(client); } catch (Exception) { Console.WriteLine("Correctly failed with invalid scope"); } Console.WriteLine("Attempting to try again with include_granted_scopes"); await this.AcquireAccessToken(newScopes, IncludeGrantedScopes.User); var clientNew = new DropboxClient(Settings.Default.AccessToken, Settings.Default.RefreshToken, ApiKey, ApiSecret, config); await GetCurrentAccount(clientNew); Console.WriteLine("Oauth Test Complete!"); Console.WriteLine("Exit with any key"); Console.ReadKey(); } catch (HttpException e) { Console.WriteLine("Exception reported from RPC layer"); Console.WriteLine(" Status code: {0}", e.StatusCode); Console.WriteLine(" Message : {0}", e.Message); if (e.RequestUri != null) { Console.WriteLine(" Request uri: {0}", e.RequestUri); } } return 0; } /// <summary> /// Handles the redirect from Dropbox server. Because we are using token flow, the local /// http server cannot directly receive the URL fragment. We need to return a HTML page with /// inline JS which can send URL fragment to local server as URL parameter. /// </summary> /// <param name="http">The http listener.</param> /// <returns>The <see cref="Task"/></returns> private async Task HandleOAuth2Redirect(HttpListener http) { var context = await http.GetContextAsync(); // We only care about request to RedirectUri endpoint. while (context.Request.Url.AbsolutePath != RedirectUri.AbsolutePath) { context = await http.GetContextAsync(); } context.Response.ContentType = "text/html"; // Respond with a page which runs JS and sends URL fragment as query string // to TokenRedirectUri. using (var file = File.OpenRead("index.html")) { file.CopyTo(context.Response.OutputStream); } context.Response.OutputStream.Close(); } /// <summary> /// Handle the redirect from JS and process raw redirect URI with fragment to /// complete the authorization flow. /// </summary> /// <param name="http">The http listener.</param> /// <returns>The <see cref="OAuth2Response"/></returns> private async Task<Uri> HandleJSRedirect(HttpListener http) { var context = await http.GetContextAsync(); // We only care about request to TokenRedirectUri endpoint. while (context.Request.Url.AbsolutePath != JSRedirectUri.AbsolutePath) { context = await http.GetContextAsync(); } var redirectUri = new Uri(context.Request.QueryString["url_with_fragment"]); return redirectUri; } /// <summary> /// Acquires a dropbox access token and saves it to the default settings for the app. /// <para> /// This fetches the access token from the applications settings, if it is not found there /// (or if the user chooses to reset the settings) then the UI in <see cref="LoginForm"/> is /// displayed to authorize the user. /// </para> /// </summary> /// <returns>A valid uid if a token was acquired or null.</returns> private async Task<string> AcquireAccessToken(string[] scopeList, IncludeGrantedScopes includeGrantedScopes) { Console.Write("Reset settings (Y/N) "); if (Console.ReadKey().Key == ConsoleKey.Y) { Settings.Default.Reset(); } Console.WriteLine(); var accessToken = Settings.Default.AccessToken; var refreshToken = Settings.Default.RefreshToken; if (string.IsNullOrEmpty(accessToken)) { try { Console.WriteLine("Waiting for credentials."); var state = Guid.NewGuid().ToString("N"); var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code, ApiKey, RedirectUri, state: state, tokenAccessType : TokenAccessType.Offline, scopeList : scopeList, includeGrantedScopes: includeGrantedScopes); var http = new HttpListener(); http.Prefixes.Add(LoopbackHost); http.Start(); System.Diagnostics.Process.Start(authorizeUri.ToString()); // Handle OAuth redirect and send URL fragment to local server using JS. await HandleOAuth2Redirect(http); // Handle redirect from JS and process OAuth response. var redirectUri = await HandleJSRedirect(http); Console.WriteLine("Exchanging code for token"); var tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(redirectUri, ApiKey, ApiSecret, RedirectUri.ToString(), state); Console.WriteLine("Finished Exchanging Code for Token"); // Bring console window to the front. SetForegroundWindow(GetConsoleWindow()); accessToken = tokenResult.AccessToken; refreshToken = tokenResult.RefreshToken; var uid = tokenResult.Uid; Console.WriteLine("Uid: {0}", uid); Console.WriteLine("AccessToken: {0}", accessToken); if (tokenResult.RefreshToken != null) { Console.WriteLine("RefreshToken: {0}", refreshToken); Settings.Default.RefreshToken = refreshToken; } if (tokenResult.ExpiresAt != null) { Console.WriteLine("ExpiresAt: {0}", tokenResult.ExpiresAt); } if (tokenResult.ScopeList != null) { Console.WriteLine("Scopes: {0}", String.Join(" ", tokenResult.ScopeList)); } Settings.Default.AccessToken = accessToken; Settings.Default.Uid = uid; Settings.Default.Save(); http.Stop(); return uid; } catch (Exception e) { Console.WriteLine("Error: {0}", e.Message); return null; } } return null; } /// <summary> /// Gets information about the currently authorized account. /// <para> /// This demonstrates calling a simple rpc style api from the Users namespace. /// </para> /// </summary> /// <param name="client">The Dropbox client.</param> /// <returns>An asynchronous task.</returns> private async Task GetCurrentAccount(DropboxClient client) { try { Console.WriteLine("Current Account:"); var full = await client.Users.GetCurrentAccountAsync(); Console.WriteLine("Account id : {0}", full.AccountId); Console.WriteLine("Country : {0}", full.Country); Console.WriteLine("Email : {0}", full.Email); Console.WriteLine("Is paired : {0}", full.IsPaired ? "Yes" : "No"); Console.WriteLine("Locale : {0}", full.Locale); Console.WriteLine("Name"); Console.WriteLine(" Display : {0}", full.Name.DisplayName); Console.WriteLine(" Familiar : {0}", full.Name.FamiliarName); Console.WriteLine(" Given : {0}", full.Name.GivenName); Console.WriteLine(" Surname : {0}", full.Name.Surname); Console.WriteLine("Referral link : {0}", full.ReferralLink); if (full.Team != null) { Console.WriteLine("Team"); Console.WriteLine(" Id : {0}", full.Team.Id); Console.WriteLine(" Name : {0}", full.Team.Name); } else { Console.WriteLine("Team - None"); } } catch (Exception e) { throw e; } } } }
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
The Dropbox Community team is active from Monday to Friday. We try to respond to you as soon as we can, usually within 2 hours.
If you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X, Facebook or Instagram.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!