cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Share your feedback on the Document Scanning Experience in the Dropbox App right here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Re: How to programmatically get the Authorization code without requiring the user approval in OAuth

How to programmatically get the Authorization code without requiring the user approval in OAuth 2.0

Ivan_
Helpful | Level 6
Go to solution

Hi,

I need to get approve code programmatically without this form via c# code 

Ivan__0-1664794638293.png

 

 this is my code

Ivan__1-1664794703052.png

How it should be modified in order to get approve code automatically without user actions ?

Thanks in advance 

1 Accepted Solution

Accepted Solutions

Здравко
Legendary | Level 20
Go to solution

@Ivan_ wrote:

...

The problem is that this code does not work in my Application. It stops at Proce/ssCodeFlowAsync method and after that the eternal loading of response begins. Sometimes eternal loading begins at HandleJSRedirect and HandleOAuth2Redirect methods, I do not know what causes such behavior.

...


@Ivan_, the code is for one time use!!! Once you get your credentials (access token and refresh token) the code isn't valid anymore! You should keep received credentials (primary the refresh token) and reuse later when needed to construct client object. Why after the authentication (you have credentials already) are you calling still handlers designate for initial authentication? :thinking_face: I cannot see a reason.

View solution in original post

14 Replies 14

Здравко
Legendary | Level 20
Go to solution

@Ivan_ wrote:

...

I need to get approve code programmatically ...


You can use redirect URL and listen to there. What actually are you using the 'http' object for? :winking_face:


@Ivan_ wrote:

...

How it should be modified in order to get approve code automatically without user actions ?

...


It's not possible for user side authentication (or least not a good idea). It's only possible on server side with pre-authentication and embedded credentials into the server, if applicable in your case.

Greg-DB
Dropbox Staff
Go to solution

@Ivan_ Здравко is correct, to receive the authorization code programmatically, you should use a redirect URI. You can find more information on how this process works in the OAuth Guide and authorization documentation.

 

Also note that it is not possible to fully automate the OAuth process where the user chooses to authorize the app and the app then receives the resulting access token and optional refresh token. This needs to be done manually by the user at least once. If your app needs to maintain long-term access without the user manually re-authorizing it repeatedly, the app should request "offline" access so that it gets a refresh token. The refresh token doesn't expire and can be stored and used repeatedly to get new short-lived access tokens whenever needed, without the user manually reauthorizing the app

 

For the official Dropbox API v2 .NET SDK in C#, you can find an example of getting and using an access token and refresh token, via a redirect URI, in the OauthBasic example (non-PKCE, meant for server-side apps) as well as in the OAuthPKCE example (PKCE, meant for client-side apps).

Ivan_
Helpful | Level 6
Go to solution

Hi Здравко

I tried to do this

Ivan__0-1664909640346.png

But I faced with such problem :

Firstly I am sending the request in order to get Approve code 

Ivan__1-1664909755923.png

After I performed confirmation in browser that I am trusting source I get this thing in browser

Ivan__2-1664909875973.png

If look closely to URL it contains code that I need to extract automatically

Ivan__3-1664909936674.png

It looks exactly as code in browser during usual approve

Ivan__6-1664910167871.png

 

However when I copied it to request for generating token

Ivan__4-1664910090596.png

I receive error

Ivan__5-1664910127506.png

 

 I do not know what I am doing wrong 

If I execute this code

Ivan__7-1664910323598.png

It will give me approve code after confirmation in browser

Ivan__8-1664910382205.png

 

 via which the token is generated successfully

But when I try to do all same with only one difference, that after user's confirmation this approve code will be extracted by program, not by user manually via this code

Ivan__9-1664910505173.png

I get error that I described above

To sum up : the only thing that I need to implement is to make automatic approve_code extraction, without making user to copy this code from browser manually after user approved that he trusts source 

 

Ivan_
Helpful | Level 6
Go to solution

Hi Здравко

I tried to do this

Ivan__0-1664909640346.png

But I faced with such problem :

Firstly I am sending the request in order to get Approve code 

Ivan__1-1664909755923.png

After I performed confirmation in browser that I am trusting source I get this thing in browser

Ivan__2-1664909875973.png

If look closely to URL it contains code that I need to extract automatically

Ivan__3-1664909936674.png

It looks exactly as code in browser during usual approve

Ivan__6-1664910167871.png

 

However when I copied it to request for generating token

Ivan__4-1664910090596.png

I receive error

Ivan__5-1664910127506.png

 

 I do not know what I am doing wrong 

If I execute this code

Ivan__7-1664910323598.png

It will give me approve code after confirmation in browser

Ivan__8-1664910382205.png

 

 via which the token is generated successfully

But when I try to do all same with only one difference, that after user's confirmation this approve code will be extracted by program via this code

Ivan__9-1664910505173.png

I get error that I described above

To sum up : the only thing that I need to implement is to make automatic approve code extraction, without making user to copy this code from browser manually

Greg-DB
Dropbox Staff
Go to solution

@Ivan_ The 127.0.0.1:52475 address seen in your screenshot is the address of a local server that should be used to programmatically receive the authorization code. Please refer to the examples as written to see how that is extracted:

Здравко
Legendary | Level 20
Go to solution

@Ivan_ wrote:

...

After I performed confirmation in browser that I am trusting source I get this thing in browser

Ivan__2-1664909875973.png

If look closely to URL it contains code that I need to extract automatically ...


Yes, that's a desired behavior. The code (together with state) is passed as a HTTP query parameter (as denoted in documentation too).

In addition to what Greg said, can be noted that pointed examples use second redirection step (don't ask me why; seems confusing, but...🤷). It can be implemented much simpler, but somebody have decided so (you are not mandated to follow the examples 1 to 1 - just get the idea out of there). For some reason the second redirection step seems doesn't comes up and so you can see the URL you are seeing. There can be different reasons, but at the beginning take a look if you give back to the browser the JS code responsible for the second redirection step and why this step fails (if you think still to follow the examples 1 to 1 - with step for second redirection).

Ivan_
Helpful | Level 6
Go to solution

Hi @Greg-DB 

Thank you for provided links 

I faced with following problem 

In console application everything works fine and token successfully generated

Ivan__2-1666893402686.png

 

Here I attach body of the await methods

Ivan__1-1666893159627.png

Some important notes : 

RedirectUri variable is local host

Ivan__3-1666893473602.png

redirectUri is bariable with value that DropBox returns to me with approve code

Ivan__4-1666893592499.png

The rest part of the code is same to the example that is provided in documentation

The problem is that this code does not work in my Application. It stops at Proce/ssCodeFlowAsync method and after that the eternal loading of response begins. Sometimes eternal loading begins at HandleJSRedirect and HandleOAuth2Redirect methods, I do not know what causes such behavior.

I want to mention that in  Console Application everything works great, without any troubles, but when I execute same code in my project app - eternal loading always starts, it looks like some troubles with threads, but I do not know what is wrong.

Here is my code in text

var http = new HttpListener();
http.Prefixes.Add(LoopbackHost);
http.Start();

var state = Guid.NewGuid().ToString("N");
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code, ApiKey,
RedirectUri, state: state, tokenAccessType: TokenAccessType.Offline, scopeList: scopeList, includeGrantedScopes: includeGrantedScopes);

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);

var tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(redirectUri, ApiKey, ApiSecret, RedirectUri.ToString(), state);
Console.WriteLine("Finished Exchanging Code for Token");
string Access = tokenResult.AccessToken;

 

-------------------------------------------------------------------------------

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();
//}
Uri redirectUri = new Uri(context.Request.UrlReferrer.ToString());
return redirectUri;
}
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();
}

 

Ivan_
Helpful | Level 6
Go to solution

Hi @Здравко 

Thank you for provided information

I faced with following problem 

In console application everything works fine and token successfully generated

Ivan__2-1666893402686.png

 

Here I attach body of the await methods

Ivan__1-1666893159627.png

Some important notes : 

RedirectUri variable is local host

Ivan__3-1666893473602.png

redirectUri is bariable with value that DropBox returns to me with approve code

Ivan__4-1666893592499.png

The rest part of the code is same to the example that is provided in documentation

The problem is that this code does not work in my Application. It stops at Proce/ssCodeFlowAsync method and after that the eternal loading of response begins. Sometimes eternal loading begins at HandleJSRedirect and HandleOAuth2Redirect methods, I do not know what causes such behavior.

I want to mention that in  Console Application everything works great, without any troubles, but when I execute same code in my project app - eternal loading always starts, it looks like some troubles with threads, but I do not know what is wrong.

Here is my code in text

var http = new HttpListener();
http.Prefixes.Add(LoopbackHost);
http.Start();

var state = Guid.NewGuid().ToString("N");
var authorizeUri = DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Code, ApiKey,
RedirectUri, state: state, tokenAccessType: TokenAccessType.Offline, scopeList: scopeList, includeGrantedScopes: includeGrantedScopes);

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);

var tokenResult = await DropboxOAuth2Helper.ProcessCodeFlowAsync(redirectUri, ApiKey, ApiSecret, RedirectUri.ToString(), state);
Console.WriteLine("Finished Exchanging Code for Token");
string Access = tokenResult.AccessToken;

 

-------------------------------------------------------------------------------

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();
//}
Uri redirectUri = new Uri(context.Request.UrlReferrer.ToString());
return redirectUri;
}
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();
}

 

Здравко
Legendary | Level 20
Go to solution

@Ivan_ wrote:

...

The problem is that this code does not work in my Application. It stops at Proce/ssCodeFlowAsync method and after that the eternal loading of response begins. Sometimes eternal loading begins at HandleJSRedirect and HandleOAuth2Redirect methods, I do not know what causes such behavior.

...


@Ivan_, the code is for one time use!!! Once you get your credentials (access token and refresh token) the code isn't valid anymore! You should keep received credentials (primary the refresh token) and reuse later when needed to construct client object. Why after the authentication (you have credentials already) are you calling still handlers designate for initial authentication? :thinking_face: I cannot see a reason.

Need more support?