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).

  • 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 Aug 26 '19 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 Aug 26 '19 at 21:36
  • Have you tried _auth: ['simple_oauth']? – user72672 Aug 30 '19 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 Sep 3 '19 at 12:36
  • Why do you have both permission and auth? – user72672 Sep 3 '19 at 18:21
0

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

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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