Skip to content

Obtaining the current user

jeff-h edited this page Dec 11, 2015 · 11 revisions
(Note: Updated 11 Dec 2015, so that users/me works for both GET and OPTIONS requests.)

It might sometimes be necessary to retrieve information about the currently authenticated user. This is not provided by RESTful out-of-the-box, but can be achieved by extending the users resource to respond to the special ID me. This will allow requests to the following example endpoints:

  • api/v1.1/users/me
  • api/users/me (if you have no later API version of the users resource.)
  • api/users/27,me,5

Note that RESTful will see the me user as the user which is authenticated via any of the restful authentication methods. The users resource by default allows any of the authentication methods (cookie, token etc).

To implement the /me special case, we will create version 1.1 of the users resource.

  • copy restful/src/Plugin/resource/Users__1_0.php to mymodule/src/Plugin/resource/entity/user/user/Users__1_1.php
  • make sure your module's .info file contains registry_autoload[] = PSR-4
  • edit Users__1_1.php and modify as follows (replacing all instances of my module with the name of your module):
<?php

/**
 * @file
 * Contains \Drupal\mymodule\Plugin\resource\entity\user\user\Users__1_1.
 */

namespace Drupal\mymodule\Plugin\resource\entity\user\user;

use Drupal\restful\Plugin\resource\ResourceInterface;

/**
 * Class Users
 * @package Drupal\mymodule\Plugin\resource\entity\user\user
 *
 * @Resource(
 *   name = "users:1.1",
 *   resource = "users",
 *   label = "Users",
 *   description = "Export the user entity.",
 *   authenticationTypes = TRUE,
 *   authenticationOptional = TRUE,
 *   dataProvider = {
 *     "entityType": "user",
 *     "bundles": {
 *       "user"
 *     },
 *   },
 *   majorVersion = 1,
 *   minorVersion = 1
 * )
 */
class Users__1_1 extends Users__1_0 implements ResourceInterface {
  /**
   * {@inheritdoc}
   */
  public function process() {
    $this->convertMeInPath();

    return parent::process();
  }

  /**
   * Replace any instances of 'me' in the $path with the authenticated user's
   * UID.
   *
   * See Drupal\restful\Plugin\resource\Resource::view()
   */
  public function convertMeInPath() {
    $path = $this->getPath();
    $ids = explode(static::IDS_SEPARATOR, $path);
    if (in_array('me', $ids)) {
      $account = $this->getAccount();

      foreach ($ids as &$id) {
        if ($id === 'me') {
          $id = $account->uid;
        }
      }

      $this->setPath(implode(static::IDS_SEPARATOR, $ids));
    }
  }
}

In essence, it's a straight "photocopy" of the Users__1_0 resource provided by RESTful, except that we override the process() function where we replace any instances of me with the appropriate user UID.

Note that we cannot use global $user; since this user may not have authenticated using cookie-based authentication, but rather one of the other auth methods provided by RESTful. The getAccount() method is provided by RESTful so we can obtain the user object which was authenticated from the REST request no matter which of the available authentication methods was used.

If the user hasn't authenticated, user 0 (i.e. anon) will be returned.

SAMPLE REQUEST

http://drupalsite.local/api/users/me

If the request also contains basic auth (containing a valid Drupal username and password), or an auth cookie or token, then RESTful will attempt to authenticate this user, but will otherwise return results for anon.

RESPONSE

Non-authenticated user:

{
  "data": {
    "type": "users",
    "attributes": {
      "label": null,
      "self": "http://drupalsite.local/api/v1.1/users/0"
    },
    "links": {
      "self": "http://drupalsite.local/api/v1.1/users"
    }
  },
  "links": {
    "self": "http://drupalsite.local/api/v1.1/users/me"
  }
}

Sample authenticated user:

{
  "data": {
    "type": "users",
    "id": "1",
    "attributes": {
      "id": "1",
      "label": "Barry",
      "self": "http://drupalsite.local/api/v1.1/users/1",
      "mail": "barry@drupalsite.local"
    },
    "links": {
      "self": "http://drupalsite.local/api/v1.1/users/1"
    }
  },
  "links": {
    "self": "http://drupalsite.local/api/v1.1/users/me"
  }
}```
Clone this wiki locally