Developers can build their own applications to manage user data in Lokalise using the OAuth 2 authentication flow.

With the OAuth 2 authentication, an application can make requests to Lokalise APIv2 on behalf of a user.

Authorization flow

OAuth 2 is an authorization protocol that allows a user to grant third-party applications access to their information on another site.

This process can be separated into three stages:

  1. The user requests an access code.

  2. The user makes a request with the access code and receives an access token. The user can receive data from Lokalise with this access token.

  3. After the access token expires the user makes a request to refresh the token.

The authorization flow is shown in more detail in the following diagram:

Register a new application

To register your app with Lokalise, you should contact our support team and provide the following information:

  • Title of your application

  • Logo of your application

    • Supported size is 150x150px.

    • Supported formats are PNG and JPG.

  • Description of your application (this field is optional).

  • Link to app website/documentation (this field is optional).

  • Required scopes. Find the list required scopes for the corresponding API endpoints in the Lokalise API description.

OAuth authorization overview

Lokalise is using OAuth 2.0 authorization protocol implementation of authorization code flow.

Prerequisites

  • The app should be registered with Lokalise. OAuth client ID ("Client ID") and OAuth client secret ("Client Secret") should be obtained.

  • Publicly available URL, where the user will be redirected after the authentication ("Redirect URI").

Step 1. Obtain Authorization Code

The app should redirect the user to the auth URL. After a successful authorization users are forwarded to the redirect URL with the authorization code as a parameter.

The request should be sent to the following URL:

https://app.lokalise.com/oauth2/auth

URL parameters:

client_id

The App Client ID received after registration

redirect_uri

The URL in your application where users will be sent after authorization.

scope

Scopes the app requires. Multiple scopes should be separated with spaces.

state

A random string used for protection against CSRF attacks. (Optional)

Example request:

https://app.lokalise.com/oauth2/auth?client_id=SomeClientID&redirect_uri=https://example.com/auth/success&scope=write_projects+read_keys&state=someRandomStateString

User will be redirected to the following URL:

https://example.com/auth/success?oauth_code=oauthCodeReceived

Step 2. Obtain access token

The app can use the authorization code received to obtain the access token. To achieve that, the app should send a POST request to the access token URL.

URL parameters:

grant_type

Specifies action to be taken (should be authorization_code)

client_id

The app client ID received after registration

client_secret

The app client secret received after registration

code

The code received after successful user authentication and redirect

Example request with cURL:

curl -X POST \ 
https://app.lokalise.com/oauth2/token \
-H "content-type: application/json" \
-d "{
\"grant_type\":\"refresh_token\",
\"client_id\":\"SomeClientID\",
\"client_secret\":\"SomeClientSecret\",
\"refresh_token\":\"someRefreshToken\"
}"

A successful response should contain the following data:

access_token

Access token to use for request authentication

refresh_token

Refresh token to use to obtain new access token after the current expires.

expires_in

Amount of seconds until the access token expires (Usually, 1 hour)

token_type

The authorization token type used. Will be required for authenticated requests. (Usually, "Bearer").

Example:

{ 
"access_token":"someAccessToken",
"refresh_token":"someRefreshToken",
"expires_in": 3600,
"token_type": "Bearer"
}


Make requests to the API

The app now can make requests to Lokalise API on behalf of the authorized user. In order to authorize a request, the Authorization request header must contain the token type and the actual access token.

Request example with cURL:

curl -H "Authorization: Bearer someAccessToken" https://api.lokalise.com/api2/projects

Step 3. Refresh token

For security reasons, the access token has a relatively short expiration time. In order to prevent user from reauthorizing the app after the token expiration, the app can obtain new access token using refresh token.

The app should send a POST request to the access token URL.

grant_type

Specifies action to be taken. (Should be "refresh_token").

client_id

The App Client ID received after registration

client_secret

The App Client Secret received after registration

refresh_token

The refresh token obtained with "authorization_code" request

Example with cURL:

curl -X POST \ 
https://app.lokalise.com/oauth2/token \
-H "content-type: application/json" \
-d "{
\"grant_type\":\"refresh_token\",
\"client_id\":\"SomeClientID\",
\"client_secret\":\"SomeClientSecret\",
\"refresh_token\":\"someRefreshToken\"
}"

A successful response should contain the following data:

access_token

Access token to use for request authentication

scope

Scopes the token has access to (see required scopes for needed API calls in descriptions below)

expires_in

Amount of seconds until the access token expires (usually, 1 hour)

token_type

The authorisation token type used. Will be required for authenticated requests. (usually, "Bearer").

Example:

{ 
"access_token":"someAccessToken",
"scope":"write_projects",
"expires_in": 3600,
"token_type": "Bearer"
}

OAuth request errors

If an OAuth request results in an error, the response will an HTTP status code 400 and the body will contain a JSON object with the following fields:

error

Error name

error_description

Error description

state

(Optional) The state string added on the Authorization code request

Example:

{ 
"error":"invalid_request",
"error_description":"Invalid post body",
"state":"someRandomStateString"
}

Example

Example of a PHP application with OAuth2 authentication:

<?php
/**
* Example of a php application with OAuth2 authentication
*/

const AUTH_ENDPOINT = 'https://app.lokalise.com/oauth2/auth';
const TOKEN_ENDPOINT = 'https://app.lokalise.com/oauth2/token';
const API_ENDPOINT = 'https://api.lokalise.com/api2';
const CLIENT_ID = 'SomeClientID';
const CLIENT_SECRET = 'SomeClientSecret';
const SCOPE = 'read_projects';

$auth_redirect_uri = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
// Should be the app static url instead

// Session will be used here as an example to store token data. Real application should use a safer and more persistent storage
session_start();

// Handle incoming requests
if ($_GET['code']) {
// requestAuthorizationCode request successful result
$_SESSION['token_data'] = obtainAccessToken($_GET['code']);
}

if (!$_SESSION['token_data']) {
// Start authentication process
requestAuthorizationCode($auth_redirect_uri);
return;
}

// App action handling
if ($_GET['action']) {
switch ($_GET['action']) {
case 'logout':
unset($_SESSION['token_data']);
header("Refresh:0");
break;
case 'list_projects':
showProjects();
break;
}
}

// App main menu
echo "<a href='?action=list_projects'>Get projects</a>";
echo "<br />";
echo "<a href='?action=logout'>Logout</a>";

// Oauth flow actions
function requestAuthorizationCode(string $auth_redirect_uri): void
{
$query = [
'client_id' => CLIENT_ID,
'redirect_uri' => $auth_redirect_uri,
'scope' => SCOPE,
'state' => uniqid(),
];
$authorizationUrl = AUTH_ENDPOINT.'?'.http_build_query($query);
// Direct user to authorization page
echo "<a href='$authorizationUrl'>Login</a>";
}

function obtainAccessToken(string $oauthCode): array
{
$payload = [
'grant_type' => 'authorization_code',
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'code' => $oauthCode,
];

$ch = curl_init(TOKEN_ENDPOINT);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Content-Type:application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_POST => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
]);

$response = curl_exec($ch);
curl_close($ch);

return json_decode($response, true);
}

// Example request to the API
function showProjects()
{
$resourceUrl = API_ENDPOINT . '/' . 'projects';
$accessToken = $_SESSION['token_data']['access_token'];
$header = ["Authorization: Bearer $accessToken"];

$curl = curl_init($resourceUrl);
curl_setopt_array($curl, [
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($curl);
curl_close($curl);

$responseDecoded = json_decode($response, true);

$projects = $responseDecoded['projects'];
echo "<ul>";
foreach ($projects as $project) {
echo "<li>{$project['name']}</li>";
}
echo "</ul>";
}

Did this answer your question?