Within a Shopify store I am making several AJAX calls and only one returns a 401 Unauthorized. The AJAX url is https://{{key}}:{{password}}#stand-around-creations.myshopify.com/admin/smart_collections.json?limit=250&fields=id,title,handle,image and it returns this:
XMLHttpRequest cannot load https://stand-around-creations.myshopify.com/admin/smart_collections.json?limit=250&fields=id,title,handle,image.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://stand-around-creations.myshopify.com' is therefore not allowed access. The response had HTTP status code 401.
I am using a private app with read access only for products, variants and collections. I know this is an authentication issue but how to solve to me isnt really clear. I have never used Basic Auth, OAuth or OAuth 2 and only have a very basic understanding of the concept. I tried searching the Shopify forums for a solution but couldn't find a solution. So how can I solve this issue or what am I doing wrong?
Related
I'm working with an API and recently something went wrong with the authentication.
The API uses jwt authentication, and when POSTing the client jwt request, instead of getting back an auth jwt, I'm getting a 401 (final) status code (or 404, depending on the library I use to handle requests...), but I'm also getting 407 and 200 when setting a verbose traceback?
I'm pretty new to handling HTTP requests so I'm curious how exactly that might be happening, where are those additional two status codes coming from?
I'm attempting to interact with the Google Sheets API and running into an inexplicable problem that I'm finally reaching out to see how anyone else may have tackled it. Put simply, I can use the in-page API Explorer tool with only the https://www.googleapis.com/auth/spreadsheets.readonly OAuth2 scope at https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/get to query my spreadsheet (just the spreadsheet ID, leaving all other fields to empty defaults) and I'll see the 200 with the response in the bottom as expected.
Of course, I can't re-use the same access token that tool uses, but if provision an access code for the same user for my own app (same scope), and make the same GET request to https://sheets.googleapis.com/v4/spreadsheets/<spreadsheetId> in Postman (again, no other fields populated), substituting the access token into the Authentication header with Bearer <accessToken>, I get a 404.
I know the file is there - I've triple checked that I'm using the same spreadsheet ID across either request and I'm consistently getting a 404 (not a 401 or 403) indicating that my access token does authenticate.
I've tried broadening my OAuth2 scopes to include the full range listed on the API Explorer:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/spreadsheets
https://www.googleapis.com/auth/spreadsheets.readonly
Of course, I don't want to have to use all those scopes for my purposes - I'd like to use the most narrow scope possible, but I also wanted to rule out that it wasn't failing to work for some scoping scenario. No difference - still a 404 every time I make the request in Postman. I've tried issuing multiple access tokens now, using accounts.google.com to invalidate the tokens for my app between re-issuances, but to no avail.
To be clear, the Google Sheets API has been enabled for my app.
In hopes that someone else has experienced the same inability to query Google's v4 REST API despite using valid access tokens, could you share how you managed to do it?
I appreciate it!
Update:
So I've been playing around with the OAuth 2.0 Playground shared in the comments and found that the authorization endpoint I was using was identical, but the token endpoint differed. This doesn't seem to matter since I used the custom option to use the alternate endpoint and the Playground was still able to work without issue just like the API Explorer.
Using the custom entries, I also entered my own app's client ID and client secret (after registering the playground redirect URI), minimizing the differences between what I'm doing in Postman and in the various Google tools. Again, my GET request to the spreadsheet works without issue.
Just to be clear, here's what I've been doing in the Playground:
In Step 1, I've specified the https://www.googleapis.com/auth/spreadsheets.readonly scope to authorize. I click the Authorize APIs button and log in with the user account.
It returns with the authorization code, so I exchange that code for the tokens via a POST to the token endpoint.
I then make a GET request to https://sheets.googleapis.com/v4/spreadsheets/<spreadsheetId> with no additional headers and it works without issue - 200 OK and all the data I'm expecting to see.
Here my approach in Postman:
Make a GET request to:
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&response_type=code&redirect_uri=https://<myDomain>/oauthResp&client_id=<appClientId>&scope=https://www.googleapis.com/auth/spreadsheets.readonly&state=abc123
Receive a response similar to the following in my browser on the redirect (since the domain intentionally 404s).
https:///oauthResp?state=abc123&code=zyx098&scope=https://www.googleapis.com/auth/spreadsheets.readonly
Make a POST request to: https://www.googleapis.com/oauth2/v4/token with a body of:
client_id=<appClientId>
client_secret=<appClientSecret>
redirect_uri=https://<myDomain>/oauthResp
grant_type=authorization_code
Receive a response similar to:
{
"access_token": "abc123",
"expires_in": 3599,
"refresh_token": "zyx098",
"scope": "https://www.googleapis.com/auth/spreadsheets.readonly",
"token_type": "Bearer"
}
Make a GET request to https://sheets.googleapis.com/v4/spreadsheets/<spreadsheetId> with a 'Content-Type' header of application/json and an 'Authorization' header of Bearer abc123 (per the access token above).
Unlike the API Explorer and the OAuth 2.0 Playground, this yields a 404 - exactly the issue I've been experiencing for no obvious reason.
Further, if I simply take the fresh access token from the Playground and drop that into Postman, I get the same 404.
Any other ideas?
I've been having a bit of trouble with receiving a code from the Sonos API for my application to then get a token for later API requests, specifically the error above. Is there any sort of test code or option to temporarily skip Oauth2 to test the API requests I already have written? Thanks!
If there was that would be a bit of a gigantic security hole. Just fix your auth code.
I'm, trying to get content of this URL
https://www.google.com/m8/feeds/contacts/default/full?oauth_token=XXXX.XXXXXXXXXXXXXXXXXXXXXXXX&v=3.0&max_result=500
but received error code 401 with description : There was an error in your request. That's all we know.
Two things to point.
A successful Oauth authentication needs to be implemented first before you are able to make a HTTP request. Be sure to use the correct scope that you need; In your case, you're using the read/write scope.
Refer to this LINK as an example on implementing OAuth on PHP.
Second, v and oauth_token are not valid URL parameters for HTTP requests. Check this Google Contacts API documentation for more information.
Hope this helps.
I'm writing a REST-ish API service the provides the ability to interact with the end user's data in other 3rd party services (themselves REST APIs) via OAuth. A common example might be publishing data from my service to a third-party service such as Facebook or Twitter.
Suppose, for example, I perform an OAuth dance with the end user and Facebook, resulting in some short-term access token that my service can use to interact with the user's Facebook account. If that access token expires and the user attempts to use my service to publish to Facebook, what sort of error do I return to the user?
401 doesn't seem quite right to me; it seems that 401 would apply to the user's auth state with MY service. 403 seems much more appropriate, but also quite generic.
401 is the way to go. Two excerpts from the RFC2616 which defines the HTTP protocol:
Section 10.4.2 (about 401):
If the request already included Authorization credentials, then the 401
response indicates that authorization has been refused for those
credentials.
This seems to be appropriate for expired tokens. There are authentication credentials, but they're refused, so the user agent must re-authenticate.
Section 10.4.4 (about 403):
The server understood the request, but is refusing to fulfill it.
Authorization will not help and the request SHOULD NOT be repeated.
This should be used when the resource can't be accessed despite the user credentials. Could be a website/API that works only on US being hit by a asian IP or a webpage that has been declared harmful and was deactivated (so the content WAS found, but the server is denying serving it).
On OAuth2, the recommended workflow depends on how the token is being passed. If passed by the Authorization header, the server may return a 401. When passed via query string parameter, the most appropriate response is a 400 Bad Request (unfortunately, the most generic one HTTP has). This is defined by section 5.2 of the OAuth2 spec https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26
There's nothing wrong with being generic, and it sounds like a 403 status would be relevant - there is nothing stopping you from providing a more human readable version that elaborates in a bit more detail why.
I think the following is a comprehensive list if you have some level of ambition when it comes to error responses.
400 Bad Request
For requests that are malformed, for example if a parameter requires an int between 0-9 and 11 has been sent. You can return this, and in the response body specify parameter x requires a value between 0 and 9
401 Unauthorized
Used only for authorization issues. The signature may be wrong, the nonce may have been used before, the timestamp that was sent is not within an acceptable time window, again, use the response body to specify more exactly why you respond with this. For the sake of clarify use this only for OAuth related errors.
403 Forbidden
Expressly to signify that an operation that is well formed, and authorized, is not possible at all (either right now, or ever). Take for example if a resource has been locked for editing by another user: use the response body to say something along the lines of Another person is editing this right now, you'll have to wait mmkay?.
403 Forbidden can also have to do with trying to reach resources. Say for example that a user has access to a resource /resource/101212/properties.json but not to /resource/999/properties.json, then you can simply state: Forbidden due to access rights in the response body.
404 Not Found
The requested resource does not exist. Or the URL simply does not successfully map to an API in your service. Specify in response body.
405 Method Not Allowed
This is to represent that the API can not be called with for example GET but another method must be used. When this is returned also you MUST return the extra response header Allow: POST, PUT, etc.