In order to obtain an access_token from Facebook, you have to transmit your app_id
, the code
you receive after the authorize request, and your app's secret_key
.
Why would I EVER transmit my secret key? This seems blatantly insecure. Is this a requirement of the OAuth 2.0 spec?
As a related question, why would I need to transmit an app_id
when my request is already signed with my consumer_key
?
I've got a working app, I just don't understand these requirements.
Client Secret (OAuth 2.0 client_secret) is a secret used by the OAuth Client to Authenticate to the Authorization Server. The Client Secret is a secret known only to the OAuth Client and the Authorization Server. Client Secret must be sufficiently random to not be guessable.
Registered OAuth applications are assigned a unique Client ID ( client_id ) and unique Client Secret ( client_secret ). By sending the client_id and the client_secret , you are letting Sell API know which application is accessing the API. Only requests to the Authorization Server require client credentials.
The OAuth 2.0 authorization framework is a protocol that allows a user to grant a third-party web site or application access to the user's protected resources, without necessarily revealing their long-term credentials or even their identity.
This is a requirement of the OAuth 2.0 spec, section 4.1.3.
If the client type is confidential or was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1
And section 3.2.1 refers to section 2.3. Specifically, section 2.3.1 says:
Alternatively, the authorization server MAY allow including the client credentials in the request body using the following parameters:
client_id
REQUIRED. The client identifier issued to the client during
the registration process described by Section 2.2.
client_secret
REQUIRED. The client secret. The client MAY omit the
parameter if the client secret is an empty string.
There are indeed other ways OAuth 2.0 offers but by choosing this approach, Facebook is well within the spec. Now why Facebook opted for this approach, only Facebook can probably answer.
Beside being a requirement of Oauth2, the client_secret needs to be used in this step to verify you are indeed who you claim.
It all boils down to why the process is like it is...
The 'code' you get back from the first request is pretty weak from a security standpoint on it's own. It could hijacked on it's way back to you in the redirect link, which I've seen frequently go to landing pages without SSL protection. Even if you're 100% HTTPS thoughout your site, everything's not fully safe. Someone could find the code from looking at the request URLs which get logged inside your web server's access logs.
Even if you've got the tightest security environment this side of Buckingham Palace controlling access to you servers, if you've been riding the tech rodeo more than a few years, you know someone's going at some point 'archive' your logs somewhere less-than-ideally secure. Probably on a USB key they left behind at starbucks...
Nothing can be don't to avoid this if you're using a server side API flow. Unlike Javascript running inside the client browser, you can't have the temp code added after the hash to prevent it from being logged, because browser clients don't send anything past the hash mark with the request. JS can intercept the redirect Url, and parse out stuff after the Hash tag, that's why there is JS Oauth2 flow that simply returns the access_token with out the additional intermediary code song and dance. No Client_Secret need on the JS side either, which is good as it's generally frown upon when you put passwords and secret keys inside javascript.
Now, to prevent this intermediary code from being used by a bad guy to obtain an access token, the Client_ID and Client_Secret is sent along so the API server can authenticate you're the who you claim to be and you have the authorization to redeem the code for an access_token. Nothing beats a shared secret!
Since the code has a very short window of use before it expires--basically meant for you to redeem it for an access_token immediate--the danger of someone stealing code and trying to brute force a Client_Secret isn't too likely.
The combination of a short window of use and the client_secret (over ssl of course) provides a which you later exchange with you client credentials
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With