can't get a token back from epic fhir auth server - hl7-fhir

I'm not getting a token back from my epic app.
I'm calling my app (PFI_app, non-prod. client id: [my_client_id]) from a browser script:
FHIR.oauth2.authorize({
'client_id':[my_client_id],
'scope':'openid, fhirUser,PATIENT.READ, PATIENT.SEARCH, OBSERVATION.READ, OBSERVATION.SEARCH',
'redirect_uri':[my_redirect_uri],
'state':'abc123',
'aud':'https://fhir.epic.com/interconnect-fhir-oauth/api/fhir/r4'
});
I get prompted to login at signin.epic.com and i use the credentials FHIR (username) and EpicFhir11!(password), which i got from this page: https://fhir.epic.com/Documentation?docId=testpatients.
at my redirect url page i use the following to get the access token:
FHIR.oauth2.ready()
.then(function(client){
myapp.smart = client
console.log(client);
})
BUT, i keep getting the following error message:
Failed to load resource: the server responded with a status of 400 (Bad Request)
app.html:39 https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token
i get another message saying: URL: https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token
unauthorized_client
this leads me to believe that i logged in with an improper user who isn't authorized.
ultimately, i don't get a token. any idea why? is it because I'm using improper login credentials and therfore that user doesn't have access to get a token.
also, I'm using fhir-client.js not, fhir-client-v2.js, is that a problem?
UPDATE:
so I just waited and token issue resolved itself. perhaps there was a time period I had to wait after changing my epic fhir app information at fhir.epic.com. I changed the "Application Audience" from patients to "clinicians and administrative users." I had been logging in to epic when prompted as an admin for many hours before I wrote this post, but I can't think of anything that I changed to my code. I just waited.
now my last remaining problem is that when I try and search for patients from the sandbox with this code:
var obs = await fetch(myapp.smart["state"]["serverUrl"]+"/Patient?address=123%20Main%20St.&address-city=Madison&address-postalcode=53703&address-state=Wisconsin&family=Mychart&gender=Female&given=Allison&telecom=608-123-4567",{
headers:{
"Accept":"application/json+fhir",
"Authorization":"Bearer"+myapp.smart["state"]["tokenResponse"]["access_token"]
}
}).then(function(data){
return data;
});
var response = await obs.json();
console.log( response );
I get another "unauthorized message":
Failed to load resource: the server responded with a status of 401 (Unauthorized) https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4/Patient?address=123%20Main%20St.&address-city=Madison&address-postalcode=53703&address-state=Wisconsin&family=Mychart&gender=Female&given=Allison&telecom=608-123-4567
this is where I got the syntax for structuring this call to the Patient.search resource:
https://fhir.epic.com/Sandbox?api=932
any ideas why I'm unauthorized to make this call? again, I'm logged in using the provider-facing app user credentials listed here: https://fhir.epic.com/Documentation?docId=testpatients (username: FHIR)
UPDATE:
so I changed the FHIR.oauth2.ready call to include the request and it worked. I'm not sure why I couldn't include the provided token as a Bearer token in fetch but the following worked:
var req = "/Patient?address=123%20Main%20St.&address-city=Madison&address-postalcode=53703&address-state=Wisconsin&family=Mychart&gender=Female&given=Allison&telecom=608-123-4567"
FHIR.oauth2.ready( client => client.request(req) ).then(function(output){
console.log(output); /* should include search results for the patient */
});
thanks for any help

To summarize, I changed the FHIR.oauth2.ready call to include the request and it worked.:
var req = "/Patient?address=123%20Main%20St.&address-city=Madison&address-postalcode=53703&address-state=Wisconsin&family=Mychart&gender=Female&given=Allison&telecom=608-123-4567"
FHIR.oauth2.ready( client => client.request(req) ).then(function(output){
console.log(output); /* should include search results for the patient */
});
In addition, I had to wait a period of time, possibly due to the fact that I made some changes in my epic fhir app.

Related

Getting CORS Error when using Google Business API

I am using google business API and trying to get location list.
I am going trough their documentation and using project from the link below as basis
https://developers.google.com/my-business/content/implement-oauth
Using that project I am able to successfully retrieve accounts list.
The problem occures when I try to retrieve locations list using accountID. Here is a link for their documentation
https://developers.google.com/my-business/content/manage-locations
Acording to documentation, to get location list for specific account, I should use following request
GET
https://mybusinessbusinessinformation.googleapis.com/v1/{accountId}/locations
Authorization: Bearer <access_token>
This is the code snippet, that I added to their sample project
function retrieveGoogleMyBusinessLocations(accessToken) {
$.ajax({
type: 'GET',
url: 'https://mybusinessbusinessinformation.googleapis.com/v1/{accID}/locations',
headers: {
'Authorization' : 'Bearer ' + accessToken
},
success: function(returnedData) {
var e = document.createElement("pre")
e.innerHTML = JSON.stringify(returnedData, undefined, 2);
document.body.appendChild(e);
}
});
}
When I do this request, it gives "CORS error".
The error in the console is following
Access to XMLHttpRequest at 'https://mybusinessbusinessinformation.googleapis.com/v1/xxx/locations' from origin 'http://localhost:8001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
GET https://mybusinessbusinessinformation.googleapis.com/v1/xxx/locations net::ERR_FAILED
From the error message it seems that server does no accept requests from localhost:8001, but if I do request to different endpoint it will return result.
For example if I change utl from
https://mybusinessbusinessinformation.googleapis.com/v1/{accID}/locations
to
https://mybusinessbusinessinformation.googleapis.com/v1/accounts/{accID}/locations?readMask=categories
With the second url it will return successfull result.
I am confused why it is allowing requests to one endpoint and blocks requests to other endpoint.
Can anyone help with this problem?
Have you tried making direct API requests via the Google Developers OAuth 2.0 Playground?
I tried to reproduce your error but got the expected 404 Not Found response for the unsupported endpoint pattern.

Youtube Data Api Search Endpoint 401 Error

I'm trying to use the Youtube search endpoint, which does not seem to require an OAuth token. I've read a few tutorials and they only pass an API key. I'm getting a "Failed to load resource: the server responded with a status of 401 ()" error in my console in Chrome Dev Tools. Specifically, looking at the Network tab I get this:
I notice it says that there is an error: "invalid_token" but I pass the api key so they must be talking about the OAuth token? I'm confused because it shouldn't need one, especially because I'm just doing a query for public data. Even the Try This API portion of the endpoint documentation does not need one. Most importantly, my call in Postman works and just pasting the endpoint in my browser directly works. Why doesn't it work? This is using an axios call from a ReactJS frontend.
const apiKey = 'MY_API_KEY';
const url = 'https://www.googleapis.com/youtube/v3/search';
const response = await axios.get(url, {
params: {
part: 'snippet',
maxResults: 5,
q: songName,
key: apiKey
}
});
What was happening was that I was using axios.defaults.headers.common['Authorization'] =Bearer ${params.access_token}; in other calls for another API. This causes default everything to have this access token! So what I did for now is delete axios.defaults.headers.common["Authorization"]; -- the solution is pretty obvious, just make sure you have no extra headers because Search is not a OAuth endpoint!

Google HomeGraph API: PERMISSION_DENIED error

I am making a smart home app using Actions On Google. I currently have a Firebase cloud function that calls the HomeGraph API with a Request Sync request.
Here's the contents of the function:
const {smarthome} = require('actions-on-google');
const app = smarthome({
key: "(My Key)"
});
//Assume UID is the id of the user that we are requesting a sync for
app.requestSync(uid).then((res) => {
return;
}, (e) => {
console.error(e);
});
In the logs for this function, I am getting the error:
{ "error": { "code": 403, "message": "The caller does not have permission", "status": "PERMISSION_DENIED" } }
This error seems like a standard Google API permission denied error response, but when would it happen in a Request Sync HomeGraph API call?
I was having this problem for quite a long time, and I decided to post the question and answer here so others don't have to spend wasted time troubleshooting.
There are two potential causes for this error to occur.
The most logical cause: make sure you provide a valid API key in the data passed in to the smarthome constructor. The example in the question is correct (of course, replace (my key) with the key you made in the console.
This was the cause of the error that I ran in to: make sure the uid you pass in to requestSync() is a valid user ID. There was a flaw in my SYNC code, therefore the user did not get created. I struggled so much on diagnosing this problem because the error message does not make sense.
Hope this helps to anyone with this problem.

Standalone Token Registration

Sending a request using the Test URL for Standalone Token Registration, I am faced with an internal server error with no indication as to what the problem is.
HTTP Status Code: 500:
HTTP Status Message: The request was
unsuccessful due to an unexpected condition encountered by the server.
The Test URL I'm POSTing to is:
https://test.sagepay.com/gateway/service/token.vsp
And the POST parameters are as follows:
VPSProtocol = 3.00
TxType = TOKEN
Vendor = MyVendor
VendorTxCode = UniqueVenderTxCode
Currency = GBP
NotificationURL = Publicly facing url
I can confirm that the Vendor is correct because I can successfully POST to the "Part of a Transaction Token Registration" URL, which returns a NextURL that I use to display the payment portal/entry.
I'm sending all of the required POST parameters, so I'm not sure where I've gone wrong. I hope someone can point me in the right direction.
EDIT: It was me being silly. I neglected to check the response from the HttpWebRequest (You'd think this would be my first port of call). It turns out that the vendor I'm using doesn't currently support a TxType of TOKEN. I'll have to contact SagePay support in order to get this enabled.

Clicking an href to our Github oAuth endpoint works, but an AJAX request to same endpoint gives a CORS error?

We are trying to implement Github oAuth in our app using Passport.js. If the user hits the endpoint by clicking an anchor tag/href, it works fine, but if we use a click handler to initiate an ajax request instead, we receive a CORS error from the Github server. Why?
Server side code:
app.get('/auth/github',
passport.authenticate('github', { scope: [ 'user:email' ] }));
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/login' }),
function(req, res) {
console.log('Github authentication successful!');
res.redirect('/');
});
Client side code (we are using React):
--> Works:
<a href='/auth/github'>Contact</a>;
--> Does Not Work - CORS error:
handleContactAuth(event) {
$.ajax({
url: '/auth/github',
method: 'GET',
success: data => console.log( 'Contact Auth response: ', data),
error: err => console.log( 'Error connecting to GitHub.', err)
});
}
NOTE: This is a click handler on the React component and is functioning fine, as the ajax request is being triggered. I'm aware we're not handling the response currently, apart from just a console.log.
--> CORS Error we see on the Client side when using AJAX method instead of href:
XMLHttpRequest cannot load https://github.com/login/oauth/authorize? response_type=code&redirect_uri=ht…auth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=our_client_code. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Any ideas? Would appreciate any insights - many thanks.
CORS error is not an error returned by the server, but one triggered by the browser if the response doesn't contain HTTP headers signaling that cross-origin requests are allowed. The endpoint you are hitting obviously isn't designed to be accessed like this.
I had the same problem and I found that at least in Google Chrome XMLHttpRequest object is restricted to same origin policy. So you may need to stick to using an anchor tag.
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
Link: https://developer.chrome.com/extensions/xhr

Resources