I am building 2 apps; a front-end, and a back-end.
The back-end will be built using Rails API + Doorkeeper Gem (oauth2 provider) while the front-end will be built using React Native.
Currently, I am using "Client Credentials Grant Flow" which works just fine at the moment. But after researching for a while, this flow shouldn't be used in a client-only app as it exposes the client_secret
if ever someone decompiles the app.
I have also read about "Implicit Grant Flow" which only requires client_id
. But this flow seems old now?
And according to this: https://auth0.com/docs/api-auth/which-oauth-flow-to-use#is-the-client-a-single-page-app-
It is recommending to use "Authorization Code Grant with PKCE" over "Implicit Grant Flow". I am able to make it work but the problem is that it still needs the client_secret
in order to get an access_token
, is this how it should be?
Here is the sample flow I am doing:
curl -X POST 'http://localhost:3000/oauth/authorize?client_id=xxxx&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=public&code_challenge=testchallenge&code_challenge_method=plain'
This will give me the following response:
{
"status": "redirect",
"redirect_uri": {
"action": "show",
"code": "8quZ-EAiKKG2EKnQiSYs3xeFRCgsIwcTbaWNdjnpyFg"
}
}
And then I will use the code above to get an access token using the request below:
curl -i http://localhost:3000/oauth/token \
-F grant_type="authorization_code" \
-F client_id="xxxx" \
-F client_secret="xxxx" \
-F code="8quZ-EAiKKG2EKnQiSYs3xeFRCgsIwcTbaWNdjnpyFg" \
-F redirect_uri="urn:ietf:wg:oauth:2.0:oob" \
-F code_verifier="testchallenge"
Now here is the problem, in order to exchange code
to an access_token
I will still be needing the client_secret
. How is it different from "Client Credentials Grant Flow" if both will just expose my client_secret
?
The above command will return the following:
{
"access_token": "nQoorBqLxQH4qFpmlx3mGG6Cd_TfX4d3L3gAGOTwrFs",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "public",
"created_at": 1595517643
}
If I don't include the client_secret
in the request here is the response:
{
"error": "invalid_client",
"error_description": "Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method."
}
So here are my questions:
- Do we really need
client_secret
to getaccess_token
on PKCE flow? - Why is it recommended to use "PKCE Flow" if it will just expose the
client_secret
? - How is it different from "Client Credentials Grant Flow" which also exposes the
client_secret
?
Doorkeeper PKCE documentation: https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-PKCE-flow