Warning message

Documentation is currently being migrated into the new system. Some pages might be temporarily missing, and some guides might appear empty. Thank you for your patience while we are improving Drupal.org documentation.

Using other authentication protocols

Last updated on
November 28, 2016 - 06:11

In the previous examples, we have used HTTP Basic authentication for all requests. You can also use other authentication protocols.

Core includes:

Contrib provides:

Enabling supported_auth

The auth method must be enabled for the specific resource and method. For example:

resources:
  'entity:node':
    GET:
      supported_formats:
        - json
      # Support both the core provided auth protocols.
      supported_auth:
        - cookie
        - http_basic

POST example with Guzzle and session cookies

Using session authentication for a POST request is a bit more complicated than HTTP Basic Authentication, because we need to provide a CSRF protection token. This is necessary to protect web browser users from malicious sites that could trigger RESTful POST requests on the user's behalf.

Example of POSTing a node with Guzzle version 4:

require_once($_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php');

use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\RequestException;

$base_url = 'http://drupal8.local';

$jar = new CookieJar();

try {

  $client = new Client([
    'base_url' => $base_url,
    'cookies' => true,
    'allow_redirects' => true,
    'debug' => true
  ]);

  $response = $client->post($base_url . '/user/login', [
    "form_params" => [
      "name"=> "admin",
      "pass"=> "admin",
      'form_id' => 'user_login_form'
    ],
    'cookies' => $jar
  ]);

  $token = $client->get($base_url . '/rest/session/token', [
    'cookies' => $jar
  ])->getBody(TRUE);

  $token = $token->__toString();

  $node = array(
    '_links' => array(
      'type' => array(
        'href' => $base_url . '/rest/type/node/article'
      )
    ),
    'title' => array(0 => array('value' => 'New node title - Cookie')),
  );

  $response = $client->post($base_url . '/entity/node', [
    'cookies' => $jar,
    'headers' => [
      'Accept' => 'application/json',
      'Content-type' => 'application/hal+json',
      'X-CSRF-Token' => $token,
    ],
    'json' => $node
  ]);
  if ($response->getStatusCode() == 201) {
    print 'Node creation successful!';
  } else {
    print "unsuccessful... keep trying";
    print_r(get_defined_vars());
  }
} catch(RequestException $e) {
  echo $e->getRequest();
  echo "\n\n";
  if ($e->hasResponse()) {
    echo $e->getResponse();
  }
}

Cookie Auth, Views and User Relationships

Basic auth is not possible with Views. Cookie Auth is on by default and will provide context (e.g. an Authored By User relationship) to a view that needs to know about the logged-in user. To have this context, the connecting client application needs to provide the session cookie. See the preceding Guzzle example for how to login and set that cookie in the client. The method will be the same for any client platform (e.g. iOS using AFNetworking). After fetching the cookie by POSTing the name/pass to the /user endpoint, subsequent REST views requests can use User relationships.

GET example with cURL and HTTP Basic

Using HTTP Basic authentication for a GET request is quite straightforward. Given the following resource configuration, which allows GET access on nodes through HTTP Basic authentication and supports hal+json format:

resources:
  'entity:node':
    GET:
      supported_formats:
        - hal_json
      supported_auth:
        - basic_auth

Note: make sure that hal and basic_auth modules are enabled.

If a node is created, its nid is 1 and the Authenticated role has the permission Access GET on Content resource, we can make the following cURL request:

curl --request GET --user myusername:mypassword --header 'Accept: application/hal+json' \
http://d8.local/node/1?_format=hal_json

And the response should be something like this:

{"_links":{"self":{"href":"http:\/\/d8.local\/node\/1"},"type":{"href":"http:\/\/d8.local\/rest\/type\/node\/page"},"http:\/\/d8.local\/rest\/relation\/node\/page\/uid":[{"href":"http:\/\/d8.local\/user\/1","lang":"en"}],"http:\/\/d8.local\/rest\/relation\/node\/page\/revision_uid":[{"href":"http:\/\/d8.local\/user\/0"}]},"uuid":[{"value":"f8e0ab5f-8066-49cf-815e-94f8f38b172b"}],"type":[{"target_id":"page"}],"langcode":[{"value":"en"}],"title":[{"value":"asdfasdf","lang":"en"}],"_embedded":{"http:\/\/d8.local\/rest\/relation\/node\/page\/uid":[{"_links":{"self":{"href":"http:\/\/d8.local\/user\/1"},"type":{"href":"http:\/\/d8.local\/rest\/type\/user\/user"}},"uuid":[{"value":"d3fdfeaf-926f-4258-a905-5fe88f1065e2"}],"lang":"en"}],"http:\/\/d8.local\/rest\/relation\/node\/page\/revision_uid":[{"_links":{"self":{"href":"http:\/\/d8.local\/user\/0"},"type":{"href":"http:\/\/d8.local\/rest\/type\/user\/user"}},"uuid":[{"value":"2cb087e9-60f5-4bf9-9905-5d3dd34483c4"}]}]},"status":[{"value":"1","lang":"en"}],"created":[{"value":"1396992603","lang":"en"}],"changed":[{"value":"1396992608","lang":"en"}],"promote":[{"value":"0","lang":"en"}],"sticky":[{"value":"0","lang":"en"}],"revision_timestamp":[{"value":"0"}],"log":[{"value":"","lang":"en"}],"body":[{"value":"<p>asdfasfd<\/p>\r\n","format":"basic_html","summary":""}]}

Cookie Auth with JavaScript

Try POSTing to user/login and setting the Accept header to application/json, and setting the Content-type header to application/x-www-form-urlencoded. Set your credentials and form_id as data. Sample request using jQuery AJAX should look like this:

$(function () {
    var settings = {
      "async": true,
      "crossDomain": true,
      "url": "http://my-d8-site.com/user/login", // Change to your Drupal URL
      "method": "POST",
      "headers": {"Content-Type": "application/x-www-form-urlencoded"},
      "data": {
        "name": "admin", // Change to your real login
        "pass": "password", // Change to your real password
        "form_id": "user_login_form"
      }
    }

    $.ajax(settings).done(function (response) {
      // Do whatever you want
    });
});