3

I have a custom module which includes a ControllerBase. The controller has a content() function that returns a JsonResponse(). The code for this function returns a complete list of a certain entity type.

I've tried using REST for this, but the entity structure is decently complicated and contains several field collections. By default, REST will just include the ID of a field collection as part of its presentation of this entity, so I've written a FieldFormatter plugin that replaces the field collection ID with a JSON object of its contents. Unfortunately, that requires significant overhead when returning an entire list of the entity type via REST, and takes 40 seconds to load. However, OAuth2 works fine with it.

Alternatively, my existing custom connector takes approximately two to three seconds to load, as it is a single sanitized SQL statement that outputs its results as a JSON. However, I only have Basic Auth working with this, attempting OAuth2 returns a 403 error. I am using the simple_oauth module.

I'm wondering if there is a way to:

  • A) improve the response time on the REST endpoint to be as good as the custom controller

    or

  • B) use OAuth2 with the custom controller. I've been looking for instructions on this but every OAuth2 resource I've come across so far assumes I'm using a REST endpoint.

edit to update: The REST endpoint is caching, which seems good as it's now loading much faster after the initial fetch, but (as is expected behaviour) the cache is flushed along with all other caches which is something we need to do fairly often, meaning the next person to access the endpoint will see an unusually slow response time. This isn't ideal, and I'd like to still investigate the custom controller I made, however adding _auth: ['oauth2'] to the YAML file is not fixing the 403 error.

2nd edit to update: This is my YAML for the custom controller, which is also not working:

connector.modulename:
  path: '/connector/modulename'
  defaults:
    _controller: \Drupal\connector\Controller\ModuleNameConnectorController::content
  requirements:
    _permission: 'view modulename entity'
  options:
    _auth: ['simple_oauth']

It does not work with _auth: ['simple_oauth'] or _auth: ['oauth2'] (403 error), but does work with _auth: ['basic_auth']. I'm using Postman to connect with a fresh (~30 sec, expiry 5 min) token. The same oauth2 token works for the REST connector. The error message I'm getting in my admin logs states:

League\OAuth2\Server\Exception\OAuthServerException: The resource owner or authorization server denied the request. in League\OAuth2\Server\Exception\OAuthServerException::accessDenied() (line 173 of C:\directory_to_my_site\vendor\league\oauth2-server\src\Exception\OAuthServerException.php).

and also issues a PHP warning stating that access was denied to Guest (not verified).

10
  • I don't have time to dig deeper (and assuming you're using the simple_oauth module), looking at the code and this, it might be as simple as adding _auth: ['oauth2'] to the options of the route for the custom controller (maybe instead of _access but I'm not sure)
    – Clive
    Commented Aug 26, 2019 at 19:58
  • @Clive Thank you! I was about to be really embarrassed that it was that easy, but I'm still getting a 403 error after changing the provider to oauth2 (I am using simple_oauth), clearing cache, and using a fresh access token. I will have to look into this tomorrow.
    – saramm1
    Commented Aug 26, 2019 at 21:36
  • Have you tried _auth: ['simple_oauth']?
    – user72672
    Commented Aug 30, 2019 at 12:48
  • @Jdrupal Thanks for the suggestion, I tried it but it's still giving me a 403 error. I'll update my question in case something's wrong with my YAML itself.
    – saramm1
    Commented Sep 3, 2019 at 12:36
  • Why do you have both permission and auth?
    – user72672
    Commented Sep 3, 2019 at 18:21

1 Answer 1

1

A) improve the response time on the REST endpoint to be as good as the custom controller

For the REST endpoint, you can use $response->addCacheableDependency() check this block for example: https://blog.dcycle.com/blog/2018-01-24/caching-drupal-8-rest-resource/ https://spinningcode.org/2017/05/cached-json-responses-in-drupal-8/

Make sure to add cache context and cache tags, carefully.

B) use OAuth2 with the custom controller. I've been looking for instructions on this but every OAuth2 resource I've come across so far assumes I'm using a REST endpoint.

Check the example from "simple_oauth_extras" sub module of "simple_oauth" https://git.drupalcode.org/project/simple_oauth/blob/8.x-3.x/simple_oauth_extras/simple_oauth_extras.routing.yml#L22

Controller is: https://git.drupalcode.org/project/simple_oauth/blob/8.x-3.x/simple_oauth_extras/src/Controller/DebugController.php#L39

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.