# Authentication farmOS includes an OAuth2 Authorization server for providing 1st and 3rd party clients access to the farmOS API. Rather than using a user's username and password to both *authorize and authenticate* a request, OAuth2 requires users to complete an *authorization flow* that generates an `access_token` to be used for authentication. Access tokens are provided to both 1st and 3rd party clients who wish to access the server's protected resources. Clients store the `access token` instead of the user's credentials, which makes it a more secure authentication method. Read more about the [OAuth 2.0 standards](https://oauth.net/2/). ## Client Libraries The [farmOS.py](https://github.com/farmOS/farmOS.py) and [farmOS.js](https://github.com/farmOS/farmOS.js) client libraries use the OAuth2 protocol to interact with the farmOS API. ## OAuth2 Bearer Tokens Once you have an OAuth2 token, you can authenticate requests to the farmOS server by including an `Authentication: Bearer {access_token}` header. ## OAuth2 Details The OAuth protocol defines a process where users *authorize* 1st and 3rd party *clients* with *scoped* access to data on the server. The following describes the details necessary for using OAuth2 authorization with a farmOS server. ### Scopes OAuth Scopes define different levels of access. The farmOS server implements scopes that represent individual roles or permissions. Users will authorize clients with one or more scopes that determine how much access they have to data on the server. The farmOS Default Roles module provides an OAuth scope for each of the default roles: `farm_manager`, `farm_worker`, and `farm_viewer`. If you are creating an integration with farmOS, see the [OAuth](/development/module/oauth) page of the farmOS module development docs for steps to create additional OAuth Scopes. ### Clients An OAuth Client represents a 1st or 3rd party integration with the farmOS server. Clients are uniquely identified by a `client_id` and can have an optional `client_secret` for private integrations. Clients are configured to allow only specific OAuth grants and can specify default `scopes` that are granted when none are requested. The core `farm_api_default_consumer` module provides a default client with `client_id = farm` that can use the `password` and `refresh_token` grant. You can use this client for general usage of the API, like writing a script that communicates with *your* farmOS server, but it comes with limitations. If you are creating an integration with farmOS, see the [OAuth](/development/module/oauth) page of the farmOS module development docs for steps to create an OAuth Client. ### Authorization Flows The [OAuth 2.0 standards](https://oauth.net/2/) outline 3 [Oauth2 Grant Types](https://oauth.net/2/grant-types/) to be used in an OAuth2 Authorization Flow - They are the *Authorization Code, Client Credentials* and *Refresh Token* Grants. The [Authorization Code](#authorization-code-grant) and [Refresh Token](#refreshing-tokens) grants are the only Authorization Flows recommended by farmOS for use with 3rd party clients. The **Client Credentials Grant** is often used for machine authentication not associated with a user account. The client credentials grant should only be used if a `client_secret` can be kept secret. If connecting to multiple farmOS servers, each server should use a different secret. This is challenging due to the nature of farmOS being a self-hosted application. The [Password Credentials Grant](#password-credentials-grant) is a legacy grant type that is [no longer recommended](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-2.4). Only use the Password Credentials Grant if the client can be trusted with a farmOS username and password (this is considered *1st party*). Even if the client is trusted, this grant type exposes the username and password and results in an increased attack surface. In most cases the **Client Credentials Grant** can be used with an OAuth client that is configured for each separate integration. #### Authorization Code Grant The Authorization Code Grant is most popular for 3rd party client authorization. Requesting resources is a four step process: **First**: the client sends a request to the farmOS server `/oauth/authorize` endpoint requesting an `Authorization Code`. The user logs in and authorizes the client to have the OAuth Scopes it is requesting. Copy this link to browser - http://localhost/oauth/authorize?response_type=code&client_id=farm&scope=farm_manager&redirect_uri=http://thirdparty/api/authorized&state=p4W8P5f7gJCIDbC1Mv78zHhlpJOidy **Second**: after the user accepts, the server redirects to the `redirect_uri` with an authorization `code` and `state` in the query parameters. Example redirect url from server: http://thirdparty/api/authorized?code=9eb9442c7a2b011fd59617635cca5421cd089943&state=p4W8P5f7gJCIDbC1Mv78zHhlpJOidy **Third**: copy the `code` and `state` from the URL into the body of a POST request. The `grant_type`, `client_id`, `client_secret` and `redirect_uri` must also be included in the POST body. The client makes a POST request to the `/oauth/token` endpoint to retrieve an `access_token` and `refresh_token`. $ curl -X POST -d "grant_type=authorization_code&code=ae4d1381cc67def1c10dc88a19af6ac30d7b5959&client_id=farm&redirect_uri=http://thirdparty/api/authorized" http://localhost/oauth/token {"access_token":"3f9212c4a6656f1cd1304e47307927a7c224abb0","expires_in":"10","token_type":"Bearer","scope":"farm_manager","refresh_token":"292810b04d688bfb5c3cee28e45637ec8ef1dd9e"} **Fourth**: the client sends the access token in the request header to access protected resources. The header is an Authorization header with a Bearer token: `Authorization: Bearer access_token` $ curl --header "Authorization: Bearer b872daf5827a75495c8194c6bfa4f90cf46c143e" http://localhost/api #### Password Credentials Grant **NOTE:** The **Password Credentials Grant** is a legacy grant type that is [no longer recommended](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-2.4). Only use the **Password Grant** if the client can be trusted with a farmOS username and password (this is considered *1st party*). **NOTE:** The [Simple OAuth Password Grant](https://www.drupal.org/project/simple_oauth_password_grant) module must be enabled to use the password grant. The Password Credentials Grant uses a farmOS `username` and `password` to retrieve an `access_token` and `refresh_token` in one step. For the user, this is the simplest type of *authorization.* Because the client can be trusted with their farmOS Credentials, a users `username` and `password` can be collected directly into a login form within the client application. These credentials are then used (not stored) to request tokens which are used for *authentication* with the farmOS server and retrieving data. Requesting protected resources is a two step process: **First**, the client sends a POST request to the farmOS server `/oauth/token` endpoint with `grant_type` set to `password` and a `username` and `password` included in the request body. $ curl -X POST -d "grant_type=password&username=username&password=test&client_id=farm&scope=farm_manager" http://localhost/oauth/token {"access_token":"e69c60dea3f5c59c95863928fa6fb860d3506fe9","expires_in":"300","token_type":"Bearer","scope":"farm_manager","refresh_token":"cead7d46d18d74daea83f114bc0b512ec4cc31c3"} **second**, the client sends the `access_token` in the request header to access protected resources. The header is an Authorization header with a Bearer token: `Authorization: Bearer access_token` $ curl --header "Authorization: Bearer e69c60dea3f5c59c95863928fa6fb860d3506fe9" http://localhost/api #### Refreshing Tokens The `refresh_token` can be used to retrieve a new `access_token` if the token has expired. It is a one step process: The client sends an authenticated request to the `/oauth/token`endpoint with `grant_type` set to `refresh_token` and includes the `refresh_token`, `client_id` and `client_secret` in the request body. $ curl -X POST -H 'Authorization: Bearer ad52c04d26c1002084501d28b59196996f0bd93f' -d 'refresh_token=52e7a0e12e8ddd08b155b3b3ee385687fef01664&grant_type=refresh_token&client_id=farm&client_secret=client_secret' http://localhost/oauth/token {"access_token":"acdbfabb736e42aa301b50fdda95d6b7fd3e7e14","expires_in":"300","token_type":"Bearer","scope":"user_access","refresh_token":"b73f4744840498a26f43447d8cf755238bfd391a"} The server responds with an `access_token` and `refresh_token` that can be used in future requests. The previous `access_token` and `refresh_token` will no longer work.