Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secure token in POST body or auth header #697

Merged
merged 5 commits into from
May 7, 2020

Conversation

ssylvia
Copy link
Member

@ssylvia ssylvia commented Apr 27, 2020

Adds two option to the IRequestOption:

  • fetchMode: specify the mode to fetch with (cors, no-cors, etc)
  • secureToken: hides the token of GET request in X-Esri-Authorization header.

Both options are disabled by default. This could become the default at a major release.

Fixes: #557

@codecov
Copy link

codecov bot commented Apr 27, 2020

Codecov Report

Merging #697 into master will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##            master      #697   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          108       108           
  Lines         1637      1644    +7     
  Branches       291       293    +2     
=========================================
+ Hits          1637      1644    +7     
Impacted Files Coverage Δ
packages/arcgis-rest-request/src/request.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2229f7b...bc13405. Read the comment docs.

Copy link
Member

@tomwayson tomwayson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ssylvia

I really like the idea of secureToken as you've designed it.

I'm less sure about fetchMode b/c I'm wary of exposing yet another fetch option via IRequestOptions. What is fetch's default mode? If it's not no-cors then couldn't we do this w/o adding fetchMode? People have the option of passing custom fetch so if they want to specify no-cors mode they could use that, right?

I'd also like @patrickarlt to have eyes on this.

@@ -14,6 +15,10 @@ export interface IRequestOptions {
* The HTTP method to send the request with.
*/
httpMethod?: HTTPMethods;
/**
* The fetch mode to send the request with.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
* Fetch mode used by the ArcGIS REST API.
*/
export type FetchMode = "cors" | "no-cors" | "same-origin";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if we need a type for this. Can we just put the string union inline in IRequestOptions for now?

Comment on lines 285 to 289
// Mixin headers from request options
fetchOptions.headers = {
...options.headers
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should move this above the blocks below. I know why you did, but I think if someone passes in an X-Esri-Authorization as well as secureToken, then that should trump what we generate.

expect(url).toEqual(
"https://www.arcgis.com/sharing/rest/content/items/43a8e51789044d9480a20089a84129ad/data"
);
expect(options.body).toContain("token=token");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also expect the method to be POST?

Copy link
Member

@tomwayson tomwayson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great @ssylvia.

I have a slight preference for my suggestion below, but let me know what you think.

I've asked the others to weigh in on this PR, if I don't hear vocal opposition we'll get this merged and released tomorrow.

Comment on lines 309 to 313
// Add token back to body with other params instead of header
if (token.length && options.secureToken) {
params.token = token;
delete requestHeaders["X-Esri-Authorization"];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are right to move the token out of the header and into the body if we have to use POST.

I only wonder if we should check for the existence of the token in the header rather than the re-check the criteria for putting it there.

Suggested change
// Add token back to body with other params instead of header
if (token.length && options.secureToken) {
params.token = token;
delete requestHeaders["X-Esri-Authorization"];
}
const headerToken = requestHeaders["X-Esri-Authorization"];
if (headerToken) {
// Add token back to body with other params instead of header
params.token = headerToken;
delete requestHeaders["X-Esri-Authorization"];
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomwayson We can do that but it will get more complicated. When passed as a header, the value is different. It's actually Bearer ${token}. Thought it would be better to use our original which we know is not modified elsewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's leave it as is

Copy link
Contributor

@patrickarlt patrickarlt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I am a little concerned that secureToken implies that tokens are insecure in other contexts. I'm not entirely sure what to rename it to however.

@tomwayson
Copy link
Member

Thanks @patrickarlt

Some name ideas:

  • noTokenInUrl: short, to the point. A little "No Country for Old Men" for my taste
  • useAuthHeaderForGet: this is a horrible name, but it does what it says
  • useAuthHeader: less horrible, but in this case it might be a little confusing when we don't for POST requests. This could be a string like 'get' | 'always', but we'd have to change the current logic to honor that.

@mpayson
Copy link
Contributor

mpayson commented May 5, 2020

hideToken?

@tomwayson tomwayson merged commit 8595fab into Esri:master May 7, 2020
@tomwayson
Copy link
Member

Thanks for this contribution and your patience, @ssylvia, it's been released as v2.13.0

@aert-nearmap
Copy link

I'm curious, why was the choice made to only put the token into the header for a GET and not a POST too (for consistency if anything)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

use an "X-Esri-Authorization" header to pass along tokens (not a query parameter)
5 participants