How to retrieve the parameters passed in a URI response

Mar 18, 2014 at 11:06 AM
I'm trying to write come code that will store files in Dropbox but am struggling to understand how to read the parameters passed back from the /authorize oauth2 call to the redirect URI I have specified in my initial /authorize request.

I have created an http_listener and added a handler via support() which does get called when Dropbox redirects to the URI I have told it to call in my /authorize request for my Dropbox app but I just can't seem to get any of the dynamic data from the URI that is passed into my handler from the http_request object passed to my handler.

I can see the URL in the IE window I spawn to allow the user to authorize the app is of the form:

http://localhost:17776/authed#access_token=CT_otxYwHiYAAAAAAAAAAXCMh15CL9ApK_di68EZr21YK3OYabcdefZ1Va1Ns6a&token_type=bearer&uid=71964212&state=GazTest Where "http://localhost:17776/authed" is the URI I've passed to the /authorize call and I now need to access the access_token, token_type, uid and state parameters which I can't unfortunately seem to figure out how to do.

Any pointers would be gratefully received - I've trawled many samples and web sites but can't find what I need - everything I call just seems to return the static elements, e.g. the original URI path. This is my first dabbling into any kind of web development so please be gentle with me.
Coordinator
Mar 18, 2014 at 7:12 PM
Edited Mar 18, 2014 at 10:16 PM
Hi garethlittlewood,

I guess when you send the /authorize request you set the query parameter "response_type=token", which is "token flow" defined in Dropbox documentation.

After you login and authorize, the IE redirects back to the listener "localhost:17776/authed" with "access_token" followed by the hashmark "#". Unfortunately, our listener cannot parse this uri fragment, not even see this "access_token" value in fiddler. This fragment is not a part of the Http request sent to the "localhost:17776/authed" listener. It is only accessible by the JavaScript running on the page.

Currently, the solution is change to "code flow" as setting "response_type=code".
for example the /authorize request uri is:
https://www.dropbox.com/1/oauth2/authorize?client_id=xyxpex9uch7elum&response_type=code&redirect_uri=http://localhost:17776/authed

After the IE redirects back to your listener with the "?code=" query, you can easily parse this "code" and send /token post request to exchange the "access_token".

Here is the test code.
#include "cpprest\http_client.h"
#include "cpprest\http_listener.h"
#include "cpprest\asyncrt_utils.h"

using namespace web::http;
using namespace web::json;
using namespace web::http::client;
using namespace utility;

int _tmain(int argc, _TCHAR* argv [])
{
    web::http::experimental::listener::http_listener listener(L"http://localhost:17776/authed");
    listener.open().wait();
    listener.support([](http_request request){
        auto result = request.relative_uri().query();
        string_t code;
        if (result.find(L"="))
        {
            code = result.substr(result.find(L"=")+1, result.size() - 1);
        }

        http_client client(L"https://www.dropbox.com/1/oauth2/token?client_id={Your Client ID}&client_secret={Your Client Secret, you must include this}&redirect_uri=http://localhost:17776/authed&grant_type=authorization_code&code=" + code);
        string_t body = L"grant_type=authorization_code&code="+code;
        http_request msg(methods::POST);
        msg.set_body(body);
        client.request(msg).then([&](http_response response){
            request.reply(200, response.extract_string().get());  // Here, you get the json data
        }).wait();
    });

    std::string line;
    std::wcout << U("Hit Enter to close the listener.");
    std::getline(std::cin, line);
    listener.close().wait();
    return 0;
}
This "code flow" will increase one more network communication. I hope this can help you.
Mar 18, 2014 at 10:27 PM
That's great, thank you for your prompt response - I thought I must be missing something very obvious! Having changed the response_type from "token" to "code", I can now get the information I require.

Many thanks