If you're new to Netflix's implementation of OAuth, please try the Netflix Authorization Walkthrough, at http://developer.netflix.com/walkthrough.
Also make sure you take a look at the Resources tab at the top of the page for additional OAuth information. You can also download Flixo, a Firefox plug-in that lets you "browse" the Netflix REST API, query its resources and view results without writing a line of code.
I have got the Objective-C OAuth code (which is setup for use on desktop MacOS X) working on the iPhone and talking to the Netflix API. There are a few things it needed and I'm blogging what I had to do at http://www.millicomputing.com - this is a "spare time" activity for me, its not an official Netflix supported platform or anything. More later....
After going through the documentation of OAuth Core 1.0 and through lots of trial and error I found out some points which I think are not properly documented here.
1. While generating the key for HMAC-SHA1 encryption the key should be a concatenation of your "Shared Secret" and Token Secret. For the first step in OAuth, while getting the unauthorized Request token you will not have a "Token Secret". But still you have to concatenate it(empty string) with your "Shared Secret" separated by a "&". (Eg: yoursharedsecret&)
2. The params in the signature base string should be alphabetically sorted.
Eg: oauth_consumer_key=<your api key>&oauth_nonce=something&oauth_signature_method=HMAC-SHA1&oauth_timestamp=123456789&oauth_version=0.1.
This whole string should be then UrlEncoded for UTF-8.
Eg: oauth_consumer_key%3Dp<your api key>%26oauth_nonce%3DXz6T9md3%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222972011%26oauth_version%3D1.0
3. The above mentioned params string should be then concatenated with the httpMethod, base url, params separated by "&"
Eg: GET&http%3A%2F%2Fapi.netflix.com%2Foauth%2Frequest_token&oauth_consumer_key%3Dp<your api key>%26oauth_nonce%3DXz6T9md3%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222972011%26oauth_version%3D1.0
4. This is then used as the data for the HMAC-SHA1 encryption and the key will be the one generated by step 1 above.
5. Then the final request url is prepared where oauth_signature parameter is added to the param list along with the other params. Params are obviously seperated by "&". The oauth_signature value must be UrlEncoded for UTF-8.
Eg: http://api.netflix.com/oauth/request_token?oauth_consumer_key=<your api key>&oauth_nonce=Xz6T9md3&oauth_signature_method=HMAC-SHA1&oauth_signature=ds2iD2xnBAPTGPvXQOfv5KP6Jj4%3D&oauth_timestamp=1222972011&oauth_version=1.0
On a successful GET request you will receive a string as response body.
Eg : oauth_token=sjevj&oauth_token_secret=7wjD2de&application_name=YourWonderfulApp&login_url=https%3A%2F%2Fapi-user.netflix.com%2Foauth%2Flogin%3Foauth_token%3Dsjevj
Make sure in the GET request that you make, you don't have "If-Modified-Since" header or set a value that is lesser than the default 1/1/1970 date. (for additional info on this see: http://developer.netflix.com/forum/read/28182).
Playing around with http://api.netflix.com/oauth/access_token it seems to give the same "Missing Required Consumer Key" no matter what parameters are passed in. Has anyone gotten this step to work?
I keep getting a 401 with (from wireshark):
GET /oauth/request_token?oauth_nonce=203148&oauth_signature_method=HMAC-SHA1&oauth_token=&oauth_timestamp=1223314760&oauth_consumer_key=<my key>&oauth_version=1.0&oauth_signature=oWvJg0%2Bg8cn8PY2YyASNEJIBTDs%3D HTTP/1.1
I am getting a 401 using the API. Here is the request:
GET http://api.netflix.com/oauth/request_token?oauth_consumer_key=<my key>&oauth_signature_method=HMACSHA1&oauth_timestamp=1223696646&oauth_nonce=7431429664365&oauth_signature=<SIG>
http://api.netflix.com/catalog/titles/movies/18704531?oauth_consumer_key=mabfqh6i3hdmbprtcp4m3xmt&oauth_nonce=679348014351483&oauth_signature_method=HMAC-SHA1&oauth_signature=JkfpxqeEXxA2eqjSZaiF%2B5eckQY%3D&oauth_timestamp=1226863772
<Some values changed in the parameters>
If I copy it directly into the browser, I get a 401 Unauthorized, Ruby spits out
/opt/local/lib/ruby/1.8/open-uri.rb:278:in `open_http': 403 Forbidden (OpenURI::HTTPError)
Here's the steps:
I create the signature (using consumer_key+"&") and create the url with the escaped signature
Don't try to get a token since I'm accessing a catalog method. The above url should just work. It works in Firefox, but maybe because I have Flixo installed and that is interfering.
Please offer any insights you can. i've already wasted too much time trying to get this to work without much success.
Also tried using the Ruby Gem but when I call get_request_token, I get a 400 "Bad Request"
gsharvard, have you seen http://mandarinsoda.com/2008/10/19/netflix-authentication-with-ruby-oauth/? It seems that the OAuth Ruby gem doesn't work with Netflix without the branch posted at http://github.com/rares/oauth/tree/master.
I've honestly read through the OAuth documentation as well as the Netflix walkthrough for using OAuth and I'm still getting hung up on step one. I'm not sure how I'm supposed to get the value I need to be using for the auth_signature parameter. I think I'm just missing something obvious here, but I'm actually getting more confused from re-reading the documentation and the above comments.
OAuth is a bit tricky to get your head around, but hopefully, here's a few things that may help:
1) If you want to do catalog searches, you don't need to get the User Authorization Token. Your APIKey (Consumer Key) and Shared Secret are all you need.
2) There was an error in our documentation. "auth_signature" is actually "oauth_signature" in one of the examples. I've corrected that.
3) Right now, we only handle HMAC-SHA1 signatures.
4) While it seems complicated, OAuth really boils down to a few things you need to include:
oauth_consumer_key: (The API Key you got from us when you registered)
oauth_timestamp: (The current universal time stamp in seconds. Usually available from something like "time();")
oauth_nonce: Nonsense crap. Seriously, just a few random characters will do here. It's just to make the URL unique and foil replay.
oauth_signature_method: HMAC-SHA1
oauth_signature: This is the hard bit. It's a value taken from the posting method (e.g. 'GET','POST', etc.), + the path (e.g. '/catalog/titles') + all the arguments with the keys and values having everything that's not a letter or a number escaped (e.g. 'foo=bar%20gorp&oauth_consumer_key=...')
Honestly, I'd use one of the OAuth libraries off the Resources page to generate that. I'd also suggest installing Flixo (also available off of the Resources page) as a "spot check" for values your code may be generating. (Kind of an advanced hint, Flixo will fill in missing values, and won't change values you specify. If you wanted, you can remove the "&oauth_signature=..." and it will recreate it from the values you specify.)
We hear you about how this is complicated, but honestly, it's still the best system out there for handling the trust issues. That said, we're happy to hear any suggestions you might have about how we can make this clearer or easier to understand.
JR, thanks for your info. I actually managed to get my head around it today after some sleep. I'm writing this all in a scripting language which has no native support for generating the SHA1 values. I ended up working around this by writing a PHP script to do the SHA1 work for me. I pass the data and key to the PHP script and the PHP script hands me back the value I need, in MIME format, for the oauth_signature. mIRC scripting was not built for this, but this was the biggest hurdle, everything else should be relatively easy now.
I'm starting to play around with the api. I've successfully gotten to the point of getting the request_token. However, when I try and exchange the request_token for the access_token I keep getting a 401 - Invalid Signature method. I've also tried obtaining the access_token / user_id from Flixo and using that to access a user queue, but I get the same error. Because I'm successfully getting the request token, it makes me believe that the problem is not with the HMAC-SHA1 algorithm, but something else.
Below is the SBS
using the key <shared_secret>&<request_secret>
GET
&http%3A%2F%2Fapi.netflix.com%2Foauth%2Faccess_token
&oauth_consumer_key%3D<api_key>
%26oauth_nonce%3D1110614947
%26oauth_signature_method%3DHMAC-SHA1
%26oauth_timestamp%3D1228847130
%26oauth_token%<request_token>
%26oauth_version%3D1.0
First off, I'm hoping that you're not sending the Signature Base String as the request. It should be a normal URL (e.g. "http://api.netflix.com/oauth/access_token?oauth_consumer_key=...") (I don't think you are, but I just want to make sure). Another thing to watch out for is that the oauth_signature value is properly encoded. (e.g. all "+" or "/" characters are converted to "%hex" values. I also STRONGLY advise you to use "%20" instead of "+" for spaces).
Honestly, if at all possible, I suggest you use an OAuth Library to do the signature generation rather than trying to roll it yourself. Can I ask what language you're developing in?
You are right, I'm not sending the SBS as my request. I just thought I'd post it to double check that it was properly formed.
I'm developing the application in JavaME (equiv. to Java 1.3). Due to the limiting nature of JavaME, I'm generating the oauth_signature via python as a server request. I will look for an oAuth Lib in python. Right now I am rolling my own using the hmac.sha1 algorithms provided by the standard python libs.
I have a developer account that allows credential POSTing. I am trying to figure out how to use the login API to POST a username and password in order to login. This API https://api-user.netflix.com/oauth/login supports this capability, with these parameters:
Parameter
Description
name
The subscriber’s name.
password
The subscriber’s password.
accept_tos
Indicates the user TOS have been accepted this parameter is present. Default value is false.
oauth_token
A valid request token.
Question is, how do I use this is I don't have an oatuh_token? Also, can I pass the default value of false to accept_tos?
If you're new to Netflix's implementation of OAuth, please try the Netflix Authorization Walkthrough, at http://developer.netflix.com/walkthrough.
Also make sure you take a look at the Resources tab at the top of the page for additional OAuth information. You can also download Flixo, a Firefox plug-in that lets you "browse" the Netflix REST API, query its resources and view results without writing a line of code.
Message edited by Kent Brewster 4 months ago
Tags
Adrian – 3 years ago
I have got the Objective-C OAuth code (which is setup for use on desktop MacOS X) working on the iPhone and talking to the Netflix API. There are a few things it needed and I'm blogging what I had to do at http://www.millicomputing.com - this is a "spare time" activity for me, its not an official Netflix supported platform or anything. More later....
Adrian from Netflix
Adrian – 3 years ago
Start here: <a href=http://millicomputing.blogspot.com/2008/09/netflix-api-and-getting-oauth-to-work.html>Netflix API and OAuth Part 1</a>
Adrian – 3 years ago
OK, first Request for Enhancement to Adam and Mike - please let us embed URLs in forum posts somehow :-)
Adam Durfee – 3 years ago
Sorry about the no HTML - it's a limit of the current system. I'll see if something can be done.
JR Conlin – 3 years ago
For those looking for an in-depth discussion on how to do oAuth authentication with our API, I suggest reading Jospeh Smarr's excellent tutorial at:
http://josephsmarr.com/2008/10/01/using-netflixs-new-api-a-step-by-step-guide/
Sundar – 3 years ago
After going through the documentation of OAuth Core 1.0 and through lots of trial and error I found out some points which I think are not properly documented here.
1. While generating the key for HMAC-SHA1 encryption the key should be a concatenation of your "Shared Secret" and Token Secret. For the first step in OAuth, while getting the unauthorized Request token you will not have a "Token Secret". But still you have to concatenate it(empty string) with your "Shared Secret" separated by a "&". (Eg: yoursharedsecret&)
2. The params in the signature base string should be alphabetically sorted.
Eg: oauth_consumer_key=<your api key>&oauth_nonce=something&oauth_signature_method=HMAC-SHA1&oauth_timestamp=123456789&oauth_version=0.1.
This whole string should be then UrlEncoded for UTF-8.
Eg: oauth_consumer_key%3Dp<your api key>%26oauth_nonce%3DXz6T9md3%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222972011%26oauth_version%3D1.0
3. The above mentioned params string should be then concatenated with the httpMethod, base url, params separated by "&"
Eg: GET&http%3A%2F%2Fapi.netflix.com%2Foauth%2Frequest_token&oauth_consumer_key%3Dp<your api key>%26oauth_nonce%3DXz6T9md3%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1222972011%26oauth_version%3D1.0
4. This is then used as the data for the HMAC-SHA1 encryption and the key will be the one generated by step 1 above.
5. Then the final request url is prepared where oauth_signature parameter is added to the param list along with the other params. Params are obviously seperated by "&". The oauth_signature value must be UrlEncoded for UTF-8.
Eg: http://api.netflix.com/oauth/request_token?oauth_consumer_key=<your api key>&oauth_nonce=Xz6T9md3&oauth_signature_method=HMAC-SHA1&oauth_signature=ds2iD2xnBAPTGPvXQOfv5KP6Jj4%3D&oauth_timestamp=1222972011&oauth_version=1.0
On a successful GET request you will receive a string as response body.
Eg : oauth_token=sjevj&oauth_token_secret=7wjD2de&application_name=YourWonderfulApp&login_url=https%3A%2F%2Fapi-user.netflix.com%2Foauth%2Flogin%3Foauth_token%3Dsjevj
Make sure in the GET request that you make, you don't have "If-Modified-Since" header or set a value that is lesser than the default 1/1/1970 date. (for additional info on this see: http://developer.netflix.com/forum/read/28182).
Thanks,
Sundar
Kallahar – 3 years ago
I'm unable to get http://api.netflix.com/oauth/access_token to work.
I'm using http://oauth.googlecode.com/svn/code/php/ but I don't think that's where the problem lies
http://api.netflix.com/oauth/access_token
?auth_version=1.0
&oauth_nonce=b0ae008de9a28ff1931ff4ec2b41d420
&oauth_timestamp=1223052691
&oauth_consumer_key=3z44pnwc4ynrxrba9btk8x7c
&oauth_token=z75x9cpzqv5ksrt7dmt3eg5n
&oauth_signature_method=HMAC-SHA1
&oauth_signature=ypZtXEa...MI%3D
(some values changed)
But when I use curl to fetch the results using a GET, I get "Missing Required Consumer Key"
Kallahar
Kallahar – 3 years ago
Playing around with http://api.netflix.com/oauth/access_token it seems to give the same "Missing Required Consumer Key" no matter what parameters are passed in. Has anyone gotten this step to work?
Kallahar
Kallahar – 3 years ago
Well I'm retarded, I had the wrong consumer key in my code. The error message should probably read "Missing or Invalid Consumer Key" though.
Keith Larrimore – 3 years ago
I keep getting a 401 with (from wireshark):
GET /oauth/request_token?oauth_nonce=203148&oauth_signature_method=HMAC-SHA1&oauth_token=&oauth_timestamp=1223314760&oauth_consumer_key=<my key>&oauth_version=1.0&oauth_signature=oWvJg0%2Bg8cn8PY2YyASNEJIBTDs%3D HTTP/1.1
Connection: close
Accept: */*
Host: api.netflix.com
HTTP/1.1 401 Unauthorized
Connection: close
X-Lighty-Magnet-Uri-Path: /oauth/request_token
X-Powered-By: PHP/5.2.6
X-Mashery-Responder: mashery-1.cust.iad.llnw.net
X-Mashery-Error-Code: ERR_403_NOT_AUTHORIZED
Content-type: text/html;charset=utf-8
Accept-Ranges: bytes
Content-Length: 17
Date: Mon, 06 Oct 2008 17:38:12 GMT
Server: lighttpd/1.4.19
Invalid signature
and I'm using the correct key... any ideas?
JR Conlin – 3 years ago
Try not passing the empty "oauth_token" value and make sure you're signing with just your shared secret.
Kevin Landry – 3 years ago
I am getting a 401 using the API. Here is the request:
GET http://api.netflix.com/oauth/request_token?oauth_consumer_key=<my key>&oauth_signature_method=HMACSHA1&oauth_timestamp=1223696646&oauth_nonce=7431429664365&oauth_signature=<SIG>
and this is the response I am seeing:
HTTP response=HTTP/1.1 401 Unauthorized
X-Lighty-Magnet-Uri-Path: /oauth/request_token
X-Powered-By: PHP/5.2.6
X-Mashery-Responder: mashery-1.cust.sjc.llnw.net
X-Mashery-Error-Code: ERR_403_NOT_AUTHORIZED
Content-type: text/html;charset=utf-8
Accept-Ranges: bytes
Content-Length: 20
Date: Sat, 11 Oct 2008 06:23:08 GMT
Server: lighttpd/1.4.19
Timestamp is invalid, HTTP status=401, Timestamp is invalid=null, HTTP request headers=GET http://api.netflix.com/oauth/request_token?oauth_consumer_key=<MY KEY>&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1223696646&oauth_nonce=7431429664365&oauth_signature=<SIG>
Any thoughts?
Michael Hart – 3 years ago
You're passing an invalid timestamp. Tip: You can use the timestamp in the error response to sync your application time if necessary.
gsharvard – 3 years ago
http://api.netflix.com/catalog/titles/movies/18704531?oauth_consumer_key=mabfqh6i3hdmbprtcp4m3xmt&oauth_nonce=679348014351483&oauth_signature_method=HMAC-SHA1&oauth_signature=JkfpxqeEXxA2eqjSZaiF%2B5eckQY%3D&oauth_timestamp=1226863772
<Some values changed in the parameters>
If I copy it directly into the browser, I get a 401 Unauthorized, Ruby spits out
/opt/local/lib/ruby/1.8/open-uri.rb:278:in `open_http': 403 Forbidden (OpenURI::HTTPError)
Here's the steps:
I create the signature (using consumer_key+"&") and create the url with the escaped signature
Don't try to get a token since I'm accessing a catalog method. The above url should just work. It works in Firefox, but maybe because I have Flixo installed and that is interfering.
Please offer any insights you can. i've already wasted too much time trying to get this to work without much success.
Also tried using the Ruby Gem but when I call get_request_token, I get a 400 "Bad Request"
txt2trade – 3 years ago
gsharvard, have you seen http://mandarinsoda.com/2008/10/19/netflix-authentication-with-ruby-oauth/? It seems that the OAuth Ruby gem doesn't work with Netflix without the branch posted at http://github.com/rares/oauth/tree/master.
Daniel – 3 years ago
I've honestly read through the OAuth documentation as well as the Netflix walkthrough for using OAuth and I'm still getting hung up on step one. I'm not sure how I'm supposed to get the value I need to be using for the auth_signature parameter. I think I'm just missing something obvious here, but I'm actually getting more confused from re-reading the documentation and the above comments.
JR Conlin – 3 years ago
Hi Daniel,
OAuth is a bit tricky to get your head around, but hopefully, here's a few things that may help:
1) If you want to do catalog searches, you don't need to get the User Authorization Token. Your APIKey (Consumer Key) and Shared Secret are all you need.
2) There was an error in our documentation. "auth_signature" is actually "oauth_signature" in one of the examples. I've corrected that.
3) Right now, we only handle HMAC-SHA1 signatures.
4) While it seems complicated, OAuth really boils down to a few things you need to include:
oauth_consumer_key: (The API Key you got from us when you registered)
oauth_timestamp: (The current universal time stamp in seconds. Usually available from something like "time();")
oauth_nonce: Nonsense crap. Seriously, just a few random characters will do here. It's just to make the URL unique and foil replay.
oauth_signature_method: HMAC-SHA1
oauth_signature: This is the hard bit. It's a value taken from the posting method (e.g. 'GET','POST', etc.), + the path (e.g. '/catalog/titles') + all the arguments with the keys and values having everything that's not a letter or a number escaped (e.g. 'foo=bar%20gorp&oauth_consumer_key=...')
Honestly, I'd use one of the OAuth libraries off the Resources page to generate that. I'd also suggest installing Flixo (also available off of the Resources page) as a "spot check" for values your code may be generating. (Kind of an advanced hint, Flixo will fill in missing values, and won't change values you specify. If you wanted, you can remove the "&oauth_signature=..." and it will recreate it from the values you specify.)
We hear you about how this is complicated, but honestly, it's still the best system out there for handling the trust issues. That said, we're happy to hear any suggestions you might have about how we can make this clearer or easier to understand.
Daniel – 3 years ago
JR, thanks for your info. I actually managed to get my head around it today after some sleep. I'm writing this all in a scripting language which has no native support for generating the SHA1 values. I ended up working around this by writing a PHP script to do the SHA1 work for me. I pass the data and key to the PHP script and the PHP script hands me back the value I need, in MIME format, for the oauth_signature. mIRC scripting was not built for this, but this was the biggest hurdle, everything else should be relatively easy now.
Kris Shinn – 3 years ago
I'm starting to play around with the api. I've successfully gotten to the point of getting the request_token. However, when I try and exchange the request_token for the access_token I keep getting a 401 - Invalid Signature method. I've also tried obtaining the access_token / user_id from Flixo and using that to access a user queue, but I get the same error. Because I'm successfully getting the request token, it makes me believe that the problem is not with the HMAC-SHA1 algorithm, but something else.
Below is the SBS
using the key <shared_secret>&<request_secret>
GET
&http%3A%2F%2Fapi.netflix.com%2Foauth%2Faccess_token
&oauth_consumer_key%3D<api_key>
%26oauth_nonce%3D1110614947
%26oauth_signature_method%3DHMAC-SHA1
%26oauth_timestamp%3D1228847130
%26oauth_token%<request_token>
%26oauth_version%3D1.0
Any ideas?
JR Conlin – 3 years ago
First off, I'm hoping that you're not sending the Signature Base String as the request. It should be a normal URL (e.g. "http://api.netflix.com/oauth/access_token?oauth_consumer_key=...") (I don't think you are, but I just want to make sure). Another thing to watch out for is that the oauth_signature value is properly encoded. (e.g. all "+" or "/" characters are converted to "%hex" values. I also STRONGLY advise you to use "%20" instead of "+" for spaces).
Honestly, if at all possible, I suggest you use an OAuth Library to do the signature generation rather than trying to roll it yourself. Can I ask what language you're developing in?
Kris Shinn – 3 years ago
You are right, I'm not sending the SBS as my request. I just thought I'd post it to double check that it was properly formed.
I'm developing the application in JavaME (equiv. to Java 1.3). Due to the limiting nature of JavaME, I'm generating the oauth_signature via python as a server request. I will look for an oAuth Lib in python. Right now I am rolling my own using the hmac.sha1 algorithms provided by the standard python libs.
cannadbt – 3 years ago
I just finished up a Silverlight tutorial where I used a small C# OAuth wrapper that I would recommend for any C# developers.
OAuth Wrapper: http://devblog.yedda.com/index.php/2007/10/18/oauth-c-basic-library/
Tutorial: http://www.switchonthecode.com/tutorials/silverlight-and-the-netflix-api
Thinking Ahead LLC – 3 years ago
Hi,
I am trying to use oauth with the rares-branch Ruby gem. I keep getting the error:
instance of OAuth::Consumer needs to have method `marshal_load'
My code, activate.rb is below. Any thoughts?
require 'oauth/consumer'
def index
@consumer = OAuth::Consumer.new("CONSUMER KEY","CONSUMER SECRET", {
:site => "http://api.netflix.com",
:request_token_url => "https://api-user.netflix.com/oauth/request_token",
:access_token_url => "http://api.netflix.com/oauth/access_token",
:authorize_url => "https://api-user.netflix.com/oauth/login",
:application_name => "AppName"})
@request_token = @consumer.get_request_token
session[:request_token]=@request_token
session[:request_token_secret]=@request_token.secret
@authorize_url = @request_token.authorize_url({
:oauth_consumer_key => "CONSUMER KEY"
:application_name => "AppName",
:oauth_callback => "http://localhost:3000/activate/callback"
})
redirect_to @authorize_url
end
def callback
@request_token=OAuth::RequestToken.new(session[:request_token],
session[:request_token_secret])
@access_token = @request_token.get_access_token
end
Robert Burdick – 3 years ago
Hello:
I have a developer account that allows credential POSTing. I am trying to figure out how to use the login API to POST a username and password in order to login. This API https://api-user.netflix.com/oauth/login supports this capability, with these parameters:
Parameter
Description
name
The subscriber’s name.
password
The subscriber’s password.
accept_tos
Indicates the user TOS have been accepted this parameter is present. Default value is false.
oauth_token
A valid request token.
Question is, how do I use this is I don't have an oatuh_token? Also, can I pass the default value of false to accept_tos?