0

I have created a custom module for authentication by using access_token. The authentication is working fine. So, I thought to create a custom contextual filter and use that as a filter by access token. Please find my code below.

namespace Drupal\simple_auth\Plugin\views\argument_default;

use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;

use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\Core\Site\Settings;

/**
 * Default argument plugin for the current user's carts.
 *
 * @ViewsArgumentDefault(
 *   id = "uid_from_simple_auth_access_token",
 *   title = @Translation("User ID from Simple Auth Acess Token")
 * )
 */
class UserFilterByAccessToken extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {

 /**
   * {@inheritdoc}
   */
  public function getArgument() {
    return $this->extractUserIdFromAccessToken();
  }

  public function getCacheTags() {
    return [];
  }

  public function getCacheContexts(){
    return [];
  }

  public function getCacheMaxAge(){
    return 0;
  }

  /**
   * Extracts the user ID from the access token.
   */
  protected function extractUserIdFromAccessToken() {
    $request = \Drupal::request();
    $access_token = $request->headers->get('access-token');

    if (!$access_token) {
      return new JsonResponse([
          "error" => "Access token is required"
      ], 401);
    }

    $storedRefreshToken = hash('sha256', $access_token . Settings::get('simple_auth_access_secret_key'));

    $query = \Drupal::database()->select('simple_auth_access_tokens', 'sart');
    $query->fields('sart', ['uid', 'expiration_time']);
    $query->condition('sart.token', $storedRefreshToken);
    $result = $query->execute()->fetchAssoc();

    return $result['uid'];
  }
}

The above code have created my contextual filter in the view. But my exact issue here is, for example,

  public function getArgument() {
    return 1;
  }

This filters the userid 1, when I check the view in browser (rest export view), and if I update the code like this

  public function getArgument() {
    return 2;
  }

I am getting the same result till clearing the cache. So I need to disable cache for this operation. I have tried many solutions but not getting what I have needed. I have tried adding cache tags and I cleared it using .module file, but it is not working.

Kindly help on this and if you need more info please reply.

2

1 Answer 1

1

I don't know the function cacheTags(), I assume you mean getCacheTags().

And you are returning the same cache tag for all your requests. A cache tag is data dependent and therefore must vary by data. The typical Drupal schema for individual cache tag strings is entity_type:primary_key. So if your data varies by user, you'd need something like

<?php

use \Drupal\Core\Cache\CacheableDependencyInterface;

class UserFilterByAccessToken extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {
  public function getCacheTags() {
    return ['user:' . $this->extractUserIdFromAccessToken()];
  }
}
3
  • 1
    I think OP also needs extends ArgumentDefaultPluginBase implements CacheableDependencyInterface {.
    – leymannx
    Mar 12 at 10:18
  • When OP searches their project for that 👆🏻 exact string they will find examples in core.
    – leymannx
    Mar 12 at 10:20
  • @hudri, Thanks for your answer. I have updated my code please check my code above. Now here is the new scenario. Check 1 - I am passing wrong access token -> I am getting empty result. Check 2 - I am passing correct access token -> I am getting the required data which is good. Check 3 - I am passing wrong token -> Here I am getting same data from Check 2, seems cache not clearing once the data is received. Mar 12 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.