postmanlabs / newman

Newman is a command-line collection runner for Postman
https://www.postman.com
Apache License 2.0
6.88k stars 1.17k forks source link

[Question] Request for clarification on "How to run a collection with OAuth2.0 using newman" #2615

Open taehoshino opened 3 years ago

taehoshino commented 3 years ago

This issue is filed by Product Support

Issue summary

  1. Newman Version (can be found via newman -v):5.5.2
  2. OS details (type, version, and architecture): Mac
  3. Are you using Newman as a library, or via the CLI? CLI
  4. Did you encounter this recently, or has this bug always been there: There are a few similar topics that are closed https://github.com/postmanlabs/newman/issues/1859, https://github.com/postmanlabs/newman/issues/1513
  5. Expected behaviour: As explained in https://github.com/postmanlabs/newman/issues/1460#issuecomment-371414062 and there should be no difference in the behaviour between running a collection in the app or newman
  6. Command / script used to run Newman: newman run newman-issue.json -e oauth.postman_environment.json --reporter-json-export output.json --reporters cli,json
  7. Sample collection, and auxiliary files (minus the sensitive details):
  8. Screenshots (if applicable):
  9. When running via collection runner, it works fine. Screen Shot 2021-02-08 at 10 49 53 am In app, the request header contains Bearer token: app_auth But when running via newman: Screen Shot 2021-02-08 at 10 51 26 am Looking at the newman output file, the request header contains Bearer token, but its value is different from the correct token generated in the app. newman_output

Steps to reproduce the problem:

  1. Create an empty collection
  2. Add request with GET https://api.spotify.com/v1/search?q=classical&type=track&market=US only - or copy the collection from https://www.postman.com/postman/workspace/postman-team-collections/collection/1559645-e1dfc9cb-3de7-4a73-82cd-602334bae284?ctx=documentation
  3. Set Authorization of the request to "Inherit from parent" Screen Shot 2021-02-08 at 10 57 05 am
  4. Go to the collection level authentication and set as below: auth
  5. Configure environment variables appropriately (by copying values from https://developer.spotify.com/dashboard/applications/
  6. Export both environment.json and collection.json and run newman command above

Questions

Christopher-Kane commented 3 years ago

I believe this issue is being opened as a result of the issue documented in https://github.com/postmanlabs/newman/issues/1513 but the reporter no longer had access to the windows machine that he had originally seen and reported the issue on. I do believe this issue is still present.

johnaschroeder commented 3 years ago

Yep, just ran into it today.

taehoshino commented 3 years ago

Hey @Christopher-Kane and @johnaschroeder!

I have discussed with my team on this issue and the issue here lies in the understanding of the nature of OAuth authentication flow against that of newman as an automation tool.

As an example, please refer to Spotify doc. OAuth is end-user authentication and the generated token needs to be refreshed every time. In Postman app, OAuth flow works as sending multiple requests (e.g. GET https://accounts.spotify.com/authorize etc) to service to prompt user to login and then retrieve token, which is then used to make a request.

On the other hand, newman is an automation tool where there is no way to prompt user to manually login. Also, due to the nature of OAuth token being temporary, the app does not export the value of generated OAuth token to .json file - this is why we are getting 401 error.

Having said that, there would be a few options:

  1. If you would like to test the generated OAuth token in newman, select 'Bearer Token' type in the app, copy and paste the value of generated OAuth token there, and export json to run in newman.
  2. Instead of end-user authentication method, use app authentication method e.g. API key or Client Credentials flow in the Spotify example.

We are sorry for creating some confusion in the first place and there is no appropriate answer available in the past issues. However, I hope this explanation clarifies a bit. Please let me know if you have further questions! We would be more than happy to answer any questions :)

johnaschroeder commented 3 years ago

Hi @taehoshino, thanks for the detailed and thoughtful reply. I have oauth2 in the cli working based on 1) above. That said, I'm confused by why this can't work. Here's what I have so far using Newman:

In the app, I have a variable for the token: image

Is it not possible to add a variable {{accessToken}} to the header, or otherwise link the pre-request token retrieved to the auth method? All the oauth2 config is in the newman JSON file under auth, so I guess i'm not following why this can't work.

FYI this is a 100% deal killer for us continuing to rely on postman. Thanks in advance for any clarifications or additional info, as I'm sure I'm missing something here.

Christopher-Kane commented 3 years ago

@johnaschroeder Hey John, if you're already using a pre-request script to grab the token, could you not just save that token to a collection level variable and then setup the collection to use that variable and set the rest of the requests to inherit auth from the collection? Because I have OAuth2.0 working on the command-line today using pre-request scripts and collection level variables in the exact way I described. The reason this no longer works for me is because of a 3rd party tool we wanted to use called Report Portal, apparently doesn't like requests for authentication while also running tests, so it would always fail. I figured if you could have newman work with basic auth on the command line with no pre-request scripts, that it would work the same way with OAuth2.0 but as we see now that assumption is incorrect.

taehoshino commented 3 years ago

@johnaschroeder Thanks for your response!

Is it not possible to add a variable {{accessToken}} to the header, or otherwise link the pre-request token retrieved to the auth method?

When auth type is set to OAuth, the app will not export the value to json. So it would work if you instead select "Bearer Token" type and then pass the value {{accessToken}}. Please do let me know if there is anything else I can help here.

andyblack19 commented 3 years ago

@taehoshino Not all OAuth2.0 requests require user interaction.

My scenario is I'm trying to use the 'Password' grant type of OAuth2.0 to generate an access token to be used for requests in my collection. This uses a client id/secret, username/password combination.

This works fine in Postman with the collection-level authorization set to 'OAuth 2.0', and other fields set appropriately. But does not work when running the collection in newman (401). I can see all the Auth settings have exported OK in the collection json.

I'd rather not have this as a Pre-request Script, as I don't want to be generating a new token for every request.

andyblack19 commented 3 years ago

This works fine in Postman with the collection-level authorization set to 'OAuth 2.0', and other fields set appropriately.

Scratch that. I've just noticed that in Postman (and in Collection Runner) after my OAuth2.0 access token timed out, it was not automatically fetching a new one for each collection run, as I expected. I had to click the 'Get New Access Token' button below the OAuth2.0 settings to get a new one. So I suspect newman does not do this automagically either.

Back to looking at the Pre-request Script solution 👎

taehoshino commented 3 years ago

@andyblack19 Yes, that is correct - app will not fetch or is able to fetch OAuth access token automatically (since it requires user-end authentication).

andyblack19 commented 3 years ago

since it requires user-end authentication

Your assumption here is incorrect. Certain OAuth2.0 grant types do NOT require user interaction, such as the ClientCredentials and Password. See https://oauth.net/2/grant-types/

rs294682 commented 3 years ago

Hello.... Did you have any resolution to fix this issue in Newman tool ??

chriswalker67 commented 3 years ago

I came across this issue late last week trying to automate file uploads via API - I could run the scripts successfully in Postman itself but the moment I tried to run the script using Newman, I would get the 401 error. The environment I'm working with doesn't need a username or password for OAuth2. I was retrieving the token using one Postman script in a collection, storing the token in a global variable called OAuth_Token and trying to use it again in a second script.

After a bit of experimentation and looking at the logs, I set the authentication in the second script to 'No Auth' and created a header. The header key was Authorization and the value is Bearer {{OAuth_Token}} (note that there were 2 space chars after 'Bearer'...)

YMMV, but it works for me - I can now upload files using the API from the command line

alexevansigg commented 3 years ago

I also couldn't get Inherit from Parent on OATH2.0 to work in Newman. Setting the token as environment variable then adding it as authorization header works however.

james-gardner commented 2 years ago

I also couldn't get Inherit from Parent on OATH2.0 to work in Newman. Setting the token as environment variable then adding it as authorization header works however.

How are you setting it as a header and can you do it globally or must it be done for each individual request?

james-gardner commented 2 years ago

Nevermind: https://github.com/postmanlabs/newman/issues/2275

Looks like setting one globally isn't supported. I might have to check out another tool.