Question

I'm using this module https://www.drupal.org/project/services_api_key_auth, it states that you can either put the api_key in query string or inside header. In query it works like this domain.com/api/pages?api_key=SOMEKEY234729372375. Passing this key and value in header doesn't work. I've browsed the module's code and found:

 $header_api_key = $request->headers->get('apikey');
    if (!empty($header_api_key)) {
      return $header_api_key;
    }

So I've tried to name my header apikey. Still no response.

Please help :)

Was it helpful?

Solution

The code that looks for the API key is in ApiKeyAuth::getKey().

  public function getKey(Request $request) {
    $form_api_key = $request->get('api_key');
    if (!empty($form_api_key)) {
      return $form_api_key;
    }

    $query_api_key = $request->query->get('api_key');
    if (!empty($form_api_key)) {
      return $query_api_key;
    }

    $header_api_key = $request->headers->get('apikey');
    if (!empty($header_api_key)) {
      return $header_api_key;
    }
    return FALSE;
  }

Effectively, the values that authentication provider looks for are:

  • api_key in $_POST data
  • api_key in the query string (which isn't used, due to a bug in the code)
  • apikey in the headers

Using the correct key name isn't sufficient. The value passed in that key must be associated to a user, or ApiKeyAuth::authenticate() will return an empty array. (It should return NULL if the authentication fails, but this should not probably cause any issue.)

  public function authenticate(Request $request) {
    // Load config entity.
    $api_key_entities = \Drupal::entityTypeManager()
      ->getStorage('api_key')
      ->loadMultiple();
    foreach ($api_key_entities as $key_item) {

      if ($this->getKey($request) == $key_item->key) {
        $accounts = $this->entityTypeManager->getStorage('user')->loadByProperties(array('uuid' => $key_item->user_uuid));
        $account = reset($accounts);

        if (isset($account)) {
          return $account;
        }
        break;
      }
    }

    return [];
  }

Keep in mind that, in the case there are more authentication providers that apply to the same route, Drupal will use just one, after sorting them according to priority using krsort(). (See AuthenticationCollector::getSortedProviders().)
In this case, it can happen the used authentication provider isn't the expected one, which is then unable to authenticate the user.

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top