How do I request an oauth token in FitBit with WWW

I am trying to connect to FitBit using the WWW class in C#. When I try to get an oauth token, it fails with a “401 Unauthorized” message. I’ve tried directly connecting via curl with, as far as I can tell, the same headers and it’s successful. Can anyone spot what I’m doing wrong?

When I enter this at the command line:

curl -i -X 'POST' 'https://api.fitbit.com/oauth/request_token' -H 'Authorization: OAuth oauth_consumer_key="9e2fe319f5154a658731f73ce8373ef6", oauth_nonce="47F7793F", oauth_signature="u4Mvy%2BfR5rk8C%2BXERSz%2Bc%2F9ppj0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1404279962", oauth_version="1.0"'

I Get:

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 02 Jul 2014 05:47:57 GMT
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 126
Connection: keep-alive
X-UA-Compatible: IE=edge,chrome=1
Set-Cookie: fhttps=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Language: en-US
X-Frame-Options: SAMEORIGIN

oauth_token=5c87cb5625ad6afdac957c7460d5c1d3&oauth_token_secret=73960a8e22f3c7c2cfb258fd8f83221e&oauth_callback_confirmed=true%                                                              

Using this code in Unity:

using UnityEngine;
using System;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;

public class Demo : MonoBehaviour 
{

	public class RequestTokenResponse
	{
		public string Token { get; set; }
		public string TokenSecret { get; set; }
	}

	// You need to register your game or application in Fitbit to get cosumer key and secret.
	// Go to this page for registration: https://dev.fitbit.com/apps/new 
	public string CONSUMER_KEY = "9e2fe319f5154a658731f73ce8373ef6";
	public string CONSUMER_SECRET = "75f4e6d41d5f4469a49e8b929dd0b6b4";
	private string RequestTokenURL = "http://api.fitbit.com/oauth/request_token";

	// Use this for initialization
	IEnumerator Start() 
    {
		byte[] dummy = new byte[1];
		dummy[0] = 0;

		String timestamp = "1404279962";
		String signature = "u4Mvy+fR5rk8C+XERSz+c/9ppj0=";

		StringBuilder parameters = new StringBuilder();
		parameters.AppendFormat("OAuth oauth_consumer_key=\"{0}\",oauth_nonce=\"{1}\",oauth_signature=\"{2}\"," + 
		                               "oauth_signature_method=\"{3}\",oauth_timestamp=\"{4}\",oauth_version=\"{5}\"", 
		                               "9e2fe319f5154a658731f73ce8373ef6",
		                               "47F7793F",
		                        		UrlEncode(signature),
		                               "HMAC-SHA1",
		                               timestamp,
		                               "1.0");

		Hashtable headers = new Hashtable();
		headers["Authorization"] = parameters.ToString();
		Debug.Log ("Authorization Header: " + headers["Authorization"]);


		WWW web = new WWW(RequestTokenURL, dummy, headers);

		yield return web;

		if (!string.IsNullOrEmpty(web.error))
		{
			Debug.Log(string.Format("GetRequestToken - failed. error : {0}", web.error));
		}
		else
		{
			String Token = Regex.Match(web.text, @"oauth_token=([^&]+)").Groups[1].Value;
			String TokenSecret = Regex.Match(web.text, @"oauth_token_secret=([^&]+)").Groups[1].Value;
			Debug.Log (string.Format ("Token: {0} TokenSecret: {1}", Token, TokenSecret));
		}
	}
		
	private static string UrlEncode(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return string.Empty;
		}
			
		value = Uri.EscapeDataString(value);
			
		// UrlEncode escapes with lowercase characters (e.g. %2f) but oAuth needs %2F
		value = Regex.Replace(value, "(%[0-9a-f][0-9a-f])", c => c.Value.ToUpper());
			
		// these characters are not escaped by UrlEncode() but needed to be escaped
		value = value
			.Replace("(", "%28")
				.Replace(")", "%29")
				.Replace("$", "%24")
				.Replace("!", "%21")
				.Replace("*", "%2A")
				.Replace("'", "%27");
		
		// these characters are escaped by UrlEncode() but will fail if unescaped!
		value = value.Replace("%7E", "~");
		
		return value;
	}
	
	// Update is called once per frame
	void Update() 
    {
	}
}

When I execute it I get:

Authorization Header: OAuth oauth_consumer_key="9e2fe319f5154a658731f73ce8373ef6",oauth_nonce="47F7793F",oauth_signature="u4Mvy%2BfR5rk8C%2BXERSz%2Bc%2F9ppj0%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1404279962",oauth_version="1.0"
UnityEngine.Debug:Log(Object)
<Start>c__Iterator0:MoveNext() (at Assets/Demo.cs:44)

GetRequestToken - failed. error : 401 Unauthorized
UnityEngine.Debug:Log(Object)
<Start>c__Iterator0:MoveNext() (at Assets/Demo.cs:53)

I figured out how to get Fitbit and Unity to work together.
I made a post breaking it down with the applicable Unity C# code to get your first set of data back from Fitbit.

The only thing that is up to you is which Webview you use to get the initial code back from your first call.

If you’re reading this and wanting to do it for Fitbit still,
Check this new blogpost as you can no longer use Webviews as I was using in my last post. This post covers how to do OAuth in Android without the use of a Webview in Android (FREE as well)