cancel
Showing results for 
Search instead for 
Did you mean: 
ben14008
Not applicable

Making cross-domain "Self" API calls?

Jump to solution

The current project I'm working on has pages saved as .html files that are iframed in as the student browses. I've discovered that there will be an issue when trying to run an API call that checks the student's grades to display them on a page.

The trouble is that the calls in the document are coming from another instance. I'm trying to make this call:

GET [MYINSTANCE].instructure.com/api/v1/courses/[COURSEID]/analytics/users/self/assignments

When I'm "inside" that document, the file is actually on another instance, "clusterXX-files", and not my actual canvas instance.

THE BIG QUESTION:

How can we make cross-domain API calls in Canvas? What will I need to do to either access the cookie token on "clusterXX" or prove to "myinstance" that the student is the one requesting the information?

EDIT 5/4/17: Added clarification and more detail.

EDIT 5/8/17: Accepted an answer. The best thing to do is to use an LTI. I was avoiding it due to reasons I'm not at liberty to discuss. I've proposed the LTI to the people who call the shots. 

Tags (4)
1 Solution

Accepted Solutions
James
Community Champion

I'm not sure if that is the issue, but it's possible you're running up against CORS that won't let the inner frame see the contents of the parent frame because they come from different domains. I believe that last week I even tried embedding the page within Canvas, but it came from a cluster server rather than our instance and it was running up against the CORS issue.

I've not done a lot of work with this, but one way to get around this might be to write an LTI where it makes API calls on behalf of the user rather than trying to get the CSRF token from the browser.

View solution in original post

7 Replies
kona
Community Coach
Community Coach

 @ben14008 , Due to the technical nature of this question I'm going to share it with the Canvas Developers group in the Community. They are the ones that work with this side of Canvas and should hopefully be able to help! In addition, you might consider joining the Developers group and checking out some of their other resources/information!

James
Community Champion

I'm not sure if that is the issue, but it's possible you're running up against CORS that won't let the inner frame see the contents of the parent frame because they come from different domains. I believe that last week I even tried embedding the page within Canvas, but it came from a cluster server rather than our instance and it was running up against the CORS issue.

I've not done a lot of work with this, but one way to get around this might be to write an LTI where it makes API calls on behalf of the user rather than trying to get the CSRF token from the browser.

View solution in original post

I've recently just tried to grab the cookie from the clusterXX instance and use its token to validate the calls but it turns out the cookie for "clusterXX" is HTTPonly so that one is out. For the time being I'm attempting to avoid making it an LTI, but I'm not sure if this is possible without it.

James
Community Champion

 @ben14008 ,

I even hate to suggest this next idea as I think there are better ways to do it, but if you have access to the custom JavaScript for the site and this project is important enough, then you might be able to write code in the parent window (Canvas) that listened for window.postMessage so it could communicate with the iframe. Then the iframe could talk to Canvas, have it fetch the data using its credentials, and then pass it back to the iframe once it was obtained.

You're essentially breaking the security the sandbox model on the iframe provides, so make sure your code only listens on the appropriate pages in case someone wants to do bad things from inside an iframe.

I've not used this myself, so I'm speaking from what I think it does rather than what I've seen it do, and I still think there are probably better ways of doing it, just adding it to the mix of possibilities.

I agree that I'm unsure of the security of this answer but it may have helped point me in another direction. I'll update my question/responses if I have any news.

m_dean
Not applicable

The two ways I know of making "cross domain" XHR requests in the browser are using CORS (which has to be setup on the target server) and "cheating" using JSONP (which again, has to be available from the target server). I don't think either of these methods will be available to you when using Canvas.

I think a big problem is trying to use the Canvas API from raw javascript in a HTML page, I don't get the impression that's what the API was designed for.

The only other way I could see doing this, without an LTI, is to setup a full web application hosted on your own server which can communicate with the API itself and displays the result on the page, which you can then place within the <iframe />.

This is a great idea Mike, and at this point, you're basically reinventing the wheel - because this is essentially what LTI does.  I'm curious why you want to avoid using LTI  @ben14008 ‌ this seems like a fairly typical use case.