Provide default parameters automatically with $res

2019-02-26 07:22发布

问题:

I'm creating a simple AngularJS app that uses Alfresco as back-end over the provided REST API.

Firstly, authentication is performed through the appropriate service which returns a token (alf_ticket) and that token must be sent as a URL parameter in the subsequent requests after a successful authentication.

As far as I'm concerned, the Alfresco REST API doesn't support to receive the token as part of the HTTP headers; that would be best option though, since it would be straightforward to solve the issue by configuring $http defaults for instance, just to mention one options I can think of.

In this scenario, I'm afraid I can only send the alf_ticket token in every request to the back-end as a parameter, for example:

GET /alfresco/s/api/people/admin/preferences?alf_ticket=TICKET_f79aa9eb2f839cefd1e1c7e4f579379ec06c33ed

I'm aware of $resource provides a mechanism for default parameters, but these are specific defaults for every instance of $resource.

So far, I have been thinking of the following approaches:

  1. Using parametrized URLs for each $resource instance (e.g. /alfresco/s/api/people/admin/preferences:alf_ticket); then provide through parameterDefault the appropriate function that gets the token from the current session data.
  2. Something similar to the approach described in this blog post, originally inspired by this other Stackoverflow question. But I find it slightly intrusive, so probably I'd go with option 1.

Ideally I would be looking for a global configuration for $resource or $http, similar to the way you can configure default headers ($httpProvider.defaults.headers), but I'm afraid such functionality is not provided by either of both services...

回答1:

Use an $http interceptor.

Create a factory function which reconfigures the request for any URL, adding the auth token to the parameters only if it is set:

app.factory('httpRequestInterceptor', function (Auth) {
  return {
    request: function (config) {
      if (Auth.token) {
        config.url =  URI(config.url).addSearch({'_auth_token':Auth.token}).toString();
      }
      return config;
    }
  };
})

(Note that I am using URI.js to add the parameters, since I patterned my answer after this blog post, where the author uses it as well)

Pass $httpProvider into your config block, and push the name string of your interceptor service into its interceptor array:

.config(function ($httpProvider) {
  $httpProvider.interceptors.push('httpRequestInterceptor');
})

Any $http requests (including those wrapped by $resource) will be intercepted and modified, if appropriate, before the browser executes them.

Plunker Demo