bruno icon indicating copy to clipboard operation
bruno copied to clipboard

Oauth2: Supported at the request level, but not at the collection level

Open clocklear opened this issue 11 months ago • 10 comments

When configuring OAuth 2.0, it would be helpful to configure once per collection instead of requiring configuration on individual requests:

Auth configuration at the request level: image

Auth configuration at the collection level: image

(This is for Bruno v1.10.0)

clocklear avatar Mar 01 '24 19:03 clocklear

For people that found this page via searching the issue, this is now possible with a little workaround in v1.11.0. Set the collection level auth as OAuth 2.0 (like Insomnia/Postman) Navigate to the "Script" pane of the collection and set the access token as a variable in the "Post response" section

  var token = res.body.access_token;
  if (token) {
    bru.setVar('oauth2_token', token)
  }

Then navigate to the "Headers" pane still in the collection settings and set the "Authorization" header as needed. i.e. image

Once you do this, you only need to "Get the token" once and then all requests in the collection will use this access token.

Full collection.bru for anything that just wants to copy that.

headers {
  Authorization: Bearer {{oauth2_token}}
}

auth {
  mode: oauth2
}

auth:oauth2 {
  grant_type: authorization_code
  callback_url: {{RedirectUrl}}
  authorization_url: {{AuthorizationUrl}}
  access_token_url: {{AccessTokenUrl}}
  client_id: {{ClientId}}
  client_secret: 
  scope: {{GatewayScope}}
  pkce: false
}

script:post-response {
  var token = res.body.access_token;
  if (token) {
    bru.setVar('oauth2_token', token)
  }
}

DO NOT change the request level settings (auth or script), leave the request level Auth settings on "No Auth"

After setting this up, you would just need to navigate to the "Auth" pane in collection settings, press "Get New Token" and you should be good to go to call the protected endpoints in the collection.

jackj93 avatar Mar 18 '24 02:03 jackj93

@jackj93 this isn't working for me either (v 1.12.1 now). Var isn't being set by the script either when hitting "Get Access Token" button on the Collection Authorization or in making a call that uses inherit authorization.

dougbreaux avatar Mar 19 '24 14:03 dougbreaux

@jackj93 did you have to install an external module for this to work? When putting the code you mention in the pre request script location on the collection, I just get this error:

Error invoking remote method 'send-http-request': ReferenceError: res is not defined

Any idea?

EirikHaughom avatar Mar 21 '24 19:03 EirikHaughom

@jackj93 this isn't working for me either (v 1.12.1 now). Var isn't being set by the script either when hitting "Get Access Token" button on the Collection Authorization or in making a call that uses inherit authorization.

In the request themselves you have to set the "No Auth"

@jackj93 did you have to install an external module for this to work? When putting the code you mention in the pre request script location on the collection, I just get this error:

Error invoking remote method 'send-http-request': ReferenceError: res is not defined

Any idea?

All the configuration I listed go in the configuration for the collection. do NOT put anything in the request settings The script is meant to be put in the "Post Response", sorry if that part wasn't clear

jackj93 avatar Mar 22 '24 02:03 jackj93

Thank you @jackj93, it works now! Retrospectively I should've seen in the code that it was going in the post response part.

EirikHaughom avatar Mar 22 '24 07:03 EirikHaughom

Update: As of v1.11.0 I see that OAuth2 is supported at the collection level, but setting auth to 'inherit' at the request level isn't supported:

image

Using @jackj93 's scripting provides a workaround: we can save the collection token as a variable and use that in requests in the appropriate place (for me, I set an Authorization header with the value Bearer {{oauth2_token}}). Is inherit going to be supported natively in the future without scripting hacks?

clocklear avatar Mar 25 '24 19:03 clocklear

In addition to the Post Request script by @jackj93, I'm using this Pre Request script on Collection level, then you don't need to add the header manually on each request:

var token = bru.getVar('oauth2_token')
if (token) {
  req.setHeader('Authorization', `Bearer ${token}`)
}

baldursson avatar May 20 '24 13:05 baldursson

Is there a way to reuse a token across multiple collections?

I have many collections but they use the same OAuth provider. So now I have to get a token for each collection individually, instead of doing it once and reusing it in all collections.

I guess a workaround would be to have only one collection per OAuth provider and group the requests in folders and subfolders.

devsales avatar Jun 24 '24 12:06 devsales

Workarounds aside (which work, thanks for that) is there intention to work on this formally? Debating the pros and cons of waiting on this to be solved upstream and permit inheritance on the collection requests when using Oauth2 instead of injecting a pre-script one every single request.

Thanks

danielloader avatar Jul 24 '24 15:07 danielloader

I am taking approach the insomnia way for this

created a request responsible for just fetching the token and storing the variable in post response

Screenshot 2024-08-01 at 00 12 19

then using the variable in header.

Screenshot 2024-08-01 at 00 12 39

Only friction with this approach is we have to fetch token manually once before using any of the api in our collection.

insomnia saves a little time in this by allowing us to directly use the attribute from some other response. Also it can auto refresh, hoping to see similar feature in bruno as well :)

image

hardiksethi22 avatar Jul 31 '24 18:07 hardiksethi22

Just a suggestion: until such time that the header can be added automatically for OAuth, perhaps this message could point people to this thread:

image

It took me 20 mins to track this down.

johnnyggalt avatar Aug 13 '24 01:08 johnnyggalt