Imagine you're going through a standard OAuth2 process to retrieve an access_token
for some third-party API. This is the usual process.
http://some-service.com/login
http://some-destination.com
. In this step, there's usually a code
parameter that comes with the request. So the actual URL looks like http://some-destination.com?code=CODE123
CODE123
to request an access_token
that can be used to authorize my future API calls. To do this, there's an endpoint that usually looks like this (I am using Nylas as an example but should be generic enough):As you can see, it requires me to POST the code from above (CODE123
) along with client_id
and client_secret
like this: http://some-service.com/oauth/token?code=CODE123&client_secret=SECRET&client_id=ID
. As a response, I get an access_token
that looks like TOKEN123
and I can use this to make API calls.
QUESTION
Until step 2, everything happens in the client side. But in step 3, I need to have client_id
and client_secret
. I don't think it's a good idea to store these values in the client side. Does that mean I need to have a backend server that has these two values, and my backend should convert CODE123
to TOKEN123
and hand it to the client side?
The authorization code grant is used when an application exchanges an authorization code for an access token. After the user returns to the application via the redirect URL, the application will get the authorization code from the URL and use it to request an access token.
OAuth 2.0 uses Access Tokens. An Access Token is a piece of data that represents the authorization to access resources on behalf of the end-user. OAuth 2.0 doesn't define a specific format for Access Tokens. However, in some contexts, the JSON Web Token (JWT) format is often used.
From your home page, open user settings and select Personal access tokens. Select + New Token. Name your token, select the organization where you want to use the token, and then set your token to automatically expire after a set number of days. Select the scopes for this token to authorize for your specific tasks.
As you probably know, the question describes the most common (and usually, the more secure) OAuth "Authorization Code" flow. To be clear, here's an approximation of the steps in this flow:
Until step 2, everything happens in the client side. But in step 3, I need to have client_id and client_secret. I don't think it's a good idea to store these values in the client side. Does that mean I need to have a backend server that has these two values[?]
You're correct, it's certainly not a good idea to store these values in the client-side application. These values—especially the client secret—must be placed on a server to protect the application's data. The user—and therefor, the client application—should never have access to these values.
The server uses its client ID and secret, along with the authorization code, to request an access token that it uses for API calls. The server may store the token it receives, along with an optional refresh token that it can use in the future to obtain a new access token without needing the user to explicitly authorize access again.
...and my backend should convert CODE123 to TOKEN123 and hand it to the client side?
At the very least, our server should handle the authorization flow to request an access token, and then pass only that token back to the client (over a secure connection).
However, at this point, the client-side application (and the user of that client) is responsible for the security of the access token. Depending on the security requirements of our application, we may want to add a layer to protect this access token from the client as well.
After the server-side application fetches the access token from the third-party service, if we pass the access token back to the client, malware running on the client machine, or an unauthorized person, could potentially obtain the access token from the client, which an attacker could then use to retrieve or manipulate the user's third-party resources through privileges granted to our application. For many OAuth services, an access token is not associated with a client. This means that anyone with a valid token can use the token to interact with the service, and illustrates why our application should only request the minimum scope of access needed when asking for authorization from the user.
To make API calls on behalf of a user more securely, the client-side application could send requests to our server, which, in turn, uses the access token that it obtained to interact with the third-party API. With this setup, the client does not need to know the value of the access token.
To improve performance, we likely want to cache the access token on the server for subsequent API calls for the duration of its lifetime. We may also want to encrypt the tokens if we store them in the application's database—just like we would passwords—so the tokens cannot be easily used in the event of a data breach.
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