title: Logging in with an account description: How to obtain authorization from a user and perform actions on their behalf. menu: docs:
weight: 40
parent: client
When we register our app and when we authorize our user, we need to define what exactly our generated token will have permission to do. This is done through the use of OAuth Scopes. Each API method has an associated scope, and can only be called if the token being used for authorization has been generated with the corresponding scope.
When authorizing a user, the scope
query parameter must be a subset of those we specified when we created our app. In our ongoing example, we specified read write push
as our scopes when we created our app, however it is a better idea to only request access to what your app will actually need through granular scopes.
See OAuth Scopes for a full list of scopes. Each API method's documentation will also specify the OAuth token type and the scopes required to call it. If an endpoint specifies read:statuses
and you have read
access, then you will be able to use that endpoint, since scopes are hierarchial.
{{< page-relref ref="api/oauth-scopes" caption="OAuth Scopes" >}}
This is similar to the authentication flow from before, but this time, we need to obtain authorization from a user as well.
First, if you have not already registered a client application, then see Creating our application on the previous page or go directly to POST /api/v1/apps for the full documentation of that method. We will need the client_id
and client_secret
for our application.
To authorize a user, request GET /oauth/authorize in a browser with the following query parameters:
https://mastodon.example/oauth/authorize
?client_id=CLIENT_ID
&scope=read+write+push
&redirect_uri=urn:ietf:wg:oauth:2.0:oob
&response_type=code
Note the following:
client_id
was obtained when registering our application.scope
must be a subset of our app's registered scopes. It is a good idea to only request what you need. See OAuth Scopes for more information.redirect_uri
is one of the URIs we registered with our app.We are still using "out of band" for this example, which means we will have to manually copy and paste the resulting code, but if you registered your application with a URI that you control, then the code will be returned as a query parameter code
by your request handler for the redirect URI. See the response section of the API method documentation for more information on this.
{{< hint style="warning" >}}
Treat the code
query parameter as if it were a password, you should ensure that it is not logged in request logs.
{{< /hint >}}
Now that we have an authorization code
, let's obtain an access token that will authenticate our requests as the authorized user. To do so, use POST /oauth/token like before, but pass the authorization code we just obtained:
curl -X POST \
-F 'client_id=your_client_id_here' \
-F 'client_secret=your_client_secret_here' \
-F 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' \
-F 'grant_type=authorization_code' \
-F 'code=user_authzcode_here' \
-F 'scope=read write push' \
https://mastodon.example/oauth/token
Note the following:
client_id
and client_secret
were provided in the response text when you registered your application.redirect_uri
must be one of the URIs defined when registering the application.grant_type
of authorization_code
, which still defaults to giving us the read
scope. However, while authorizing our user, we requested a certain scope
-- pass the exact same value here.code
can only be used once. If you need to obtain a new token, you will need to have the user authorize again by repeating the above Authorize the user step.The response of this method is a Token entity. We will need the access_token
value. Once you have the access token, save it in your local cache.
{{< hint style="warning" >}}
Treat the access_token
as if it were a password. We recommend you encrypt this value when storing in your cache, to prevent accidental credential exposure.
{{< /hint >}}
To use it in requests, add the HTTP header Authorization: Bearer <access_token>
to any API call that requires OAuth (i.e., one that is not publicly accessible).
Let's verify that our obtained credentials are working by calling GET /api/v1/accounts/verify_credentials:
curl \
-H 'Authorization: Bearer <access_token>' \
https://mastodon.example/api/v1/accounts/verify_credentials
If we've obtained our token and formatted our request correctly, we should see our details returned to us as an Account entity, with the source
parameter included.
With our OAuth token for the authorized user, we can now perform any action as that user that is within our token's scope.