App login provides your users access to premium content and services on your behalf. In this scenario, your app accesses content using hard-coded credentials that belong to your registered app (see using a proxy service to address this potential security risk). Users are not prompted to log in because they are logged in with your app's credentials. Using this model, users have access to any public resources you have access to, and consume your service credits for premium content. There are certain limitations and restrictions using app login.

Note:

If you are authoring an app for the ArcGIS Marketplace you must use Named User Login for your app.

The first step in this process is to register an application on ArcGIS Online or ArcGIS for Developers to obtain the necessary application credentials used with the authentication process.

Registering your application

When you register your application with ArcGIS Online you are given credentials that allow you to initiate named user login or app login. Follow these steps to register your app and generate your credentials:

  1. If you do not already have an account, sign up for either an ArcGIS Developer Account or an ArcGIS Online Organizational Trial.
  2. Sign in to ArcGIS for Developers.
  3. Go to the applications list.
  4. Select "New Application".
  5. Once you have registered your application you will see the application overview. Locate your client_id and client_secret, shown below.

    Application Overview.
6. Use your client_id and client_secret to get a token.

Note:

You can also register your apps on ArcGIS Online or in your own on-premise portal.

Getting a token

Once you have registered your application and obtained a client_id and client_secret, you implement app login to obtain a token. The path to follow from here will depend on which SDK you choose to implement your app with.

Using the ArcGIS API for JavaScript

If you are using the ArcGIS API for JavaScript refer to the guide for working with secure services.

Using an ArcGIS Runtime SDK

If you are implementing your app using one of the ArcGIS Runtime SDKs then continue with the authentication guide for your platform.

Using REST

When you are not using one of the ArcGIS SDKs you can implement app login with any platform of your choosing as long as you can generate HTTPS POST requests and receive JSON responses. Following these instructions:

App Login

  1. Your application makes a POST request to https://www.arcgis.com/sharing/rest/oauth2/token/ with your client_id and client_secret.
  2. An access_token is contained in the JSON response.
  3. Pass the access_token whenever a token parameter is required in a request.

Token endpoint

ArcGIS Online: https://www.arcgis.com/sharing/rest/oauth2/token/
On-premise ArcGIS Portal: https://<host>:<port>/<subdirectory>/sharing/rest/oauth2/token

A token can be generated using only the POST method over HTTPS.

Request parameters

Parameter Required Description
client_id The client_id of a registered application.
client_secret The client_secret of a registered application.
grant_type client_credentials The OAuth 2.0 grant type of client_credentials is required with every request.
expiration Controls how long the generated token will last, 120 minutes by default. can be set up to 20160 minutes (2 weeks).

Response object

{
    "access_token": "J-S0KLOl5_8UIqzZfmjPp6KQQeN5rnDRxRKB73n7B2hxuuI6Fec09IsIk0n8a0j-LoBskkio0I5fL0sY5iLf1J8lfhgq1gdaOAB15sm2wEaRooZbWz87bWptfGOMlqfFCoGRwF9n0h3tOd21lMyB9g..",
    "expires_in": 86400
}

Examples

import requests  # pip install requests

def get_token():
    params = {
        'client_id': "YOUR_APPLICATIONS_CLIENT_ID",
        'client_secret': "YOUR_APPLICATIONS_CLIENT_SECRET",
        'grant_type': "client_credentials"
    }

    request = requests.get('https://www.arcgis.com/sharing/oauth2/token',
                           params=params)
    response = request.json()
    token = response["access_token"]
    return token

token = get_token()
print(token)
var request = require('request'); // npm install request

// generate a token with your client id and client secret
request.post({
    url: 'https://www.arcgis.com/sharing/rest/oauth2/token/',
    json: true,
    form: {
      'f': 'json',
      'client_id': 'YOUR_APPLICATIONS_CLIENT_ID',
      'client_secret': 'YOUR_APPLICATIONS_CLIENT_SECRET',
      'grant_type': 'client_credentials',
      'expiration': '1440'
    }
}, function(error, response, body){
    console.log(body.access_token);
});
<?php
$params = array(
    'client_id' => "YOUR_APPLICATIONS_CLIENT_ID",
    'client_secret' => "YOUR_APPLICATIONS_CLIENT_SECRET",
    'grant_type' => 'client_credentials',
    'f' => 'json'
);

try {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://www.arcgis.com/sharing/oauth2/token/");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    $response = curl_exec($ch);
} catch (Exception $e) {
    error_log($e->getMessage(), 0);
}

$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$body = substr($response, $header_size);
$json = json_decode($body, true);
$token = $json['access_token'];
echo $token;
require 'json'
require 'net/http'

response = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
  f: 'json',
  client_id: 'YOUR_APPLICATIONS_CLIENT_ID',
  client_secret: 'YOUR_APPLICATIONS_CLIENT_SECRET',
  grant_type: 'client_credentials'

token = JSON.parse(response.body)['access_token']

puts token
package main

import (
  "encoding/json"
  "fmt"
  "io/ioutil"
  "net/http"
  "net/url"
)

type TokenResponse struct {
  AccessToken string `json:"access_token"`
  ExpiresIn   int    `json:"expires_in"`
}

func main() {
  resp, _ := http.PostForm("https://www.arcgis.com/sharing/rest/oauth2/token",
    url.Values{"f": {"json"}, "client_id": {"abcdef"}, "client_secret": {"zyxwuv"}, "grant_type": {"client_credentials"}})
  defer resp.Body.Close()
  body, _ := ioutil.ReadAll(resp.Body)

  var tr TokenResponse
  json.Unmarshal(body, &tr)

  fmt.Println(tr.AccessToken)
}
# generate a token with your client id and client secret
curl -X POST \
    -d "f=json" \
    -d "client_id=YOUR_APPLICATIONS_CLIENT_ID" \
    -d "client_secret=YOUR_APPLICATIONS_CLIENT_SECRET" \
    -d "grant_type=client_credentials" \
    -d "expiration=1440" \
     https://www.arcgis.com/sharing/rest/oauth2/token/

Using a token

Once you have a token you can pass that token with a request to authenticate. Below are some examples of using a token with the GeoEnrichment service to query demographic data.

import requests  # pip install requests

params = {
    'f': 'json',
    'token': 'J-S0KLOl5_8UIqzZfmjPp6KQQeN5rnDRxRKB73n7B2hxuuI6Fec09IsIk0n8a0j-LoBskkio0I5fL0sY5iLf1J8lfhgq1gdaOAB15sm2wEaRooZbWz87bWptfGOMlqfFCoGRwF9n0h3tOd21lMyB9g..',
    'studyAreas': '[{"geometry":{"x":-117.1956,"y":34.0572}}]'
}

url = 'http://geoenrich.arcgis.com/arcgis/rest/services/World/GeoenrichmentServer/Geoenrichment/enrich'
data = requests.post(url, params=params)

print(data.json())
var request = require('request'); // npm install request

request.post({
    url: 'http://geoenrich.arcgis.com/arcgis/rest/services/World/GeoenrichmentServer/Geoenrichment/enrich',
    json:true,
    form: {
      f: 'json',
      token: 'J-S0KLOl5_8UIqzZfmjPp6KQQeN5rnDRxRKB73n7B2hxuuI6Fec09IsIk0n8a0j-LoBskkio0I5fL0sY5iLf1J8lfhgq1gdaOAB15sm2wEaRooZbWz87bWptfGOMlqfFCoGRwF9n0h3tOd21lMyB9g..',
      studyAreas: '[{"geometry":{"x":-117.1956,"y":34.0572}}]'
    }
  }, function(error, response, body){
    console.log(body);
  });
require 'json'
require 'net/http'

enrich = Net::HTTP.post_form URI('http://geoenrich.arcgis.com/arcgis/rest/services/World/GeoenrichmentServer/Geoenrichment/enrich'),
  f: 'json',
  token: 'J-S0KLOl5_8UIqzZfmjPp6KQQeN5rnDRxRKB73n7B2hxuuI6Fec09IsIk0n8a0j-LoBskkio0I5fL0sY5iLf1J8lfhgq1gdaOAB15sm2wEaRooZbWz87bWptfGOMlqfFCoGRwF9n0h3tOd21lMyB9g..',
  studyAreas: '[{"geometry":{"x":-117.1956,"y":34.0572}}]'

puts JSON.parse(enrich.body)
curl -X POST \
     -d "f=json" \
     -d "token=J-S0KLOl5_8UIqzZfmjPp6KQQeN5rnDRxRKB73n7B2hxuuI6Fec09IsIk0n8a0j-LoBskkio0I5fL0sY5iLf1J8lfhgq1gdaOAB15sm2wEaRooZbWz87bWptfGOMlqfFCoGRwF9n0h3tOd21lMyB9g.." \
     -d "studyAreas=[{'geometry':{'x':-117.1956,'y':34.0572}}]" \
     http://geoenrich.arcgis.com/arcgis/rest/services/World/GeoenrichmentServer/Geoenrichment/enrich

Token errors

When a request does not succeed you will receive the following response:

{
  "error":{
    "code":400,
    "error":"invalid_request",
    "error_description":"code expired",
    "message":"code expired",
    "details":[]
  }
}

Error codes generally range 400-499 as standard HTTP status codes and the message indicates details of the failure. Common failures are due to an expired or invalid token. In this case generate a new token and try your request again.

Available content and services

App login can be used to access any of these services: