Navigating the Cookie-Free Future with LTI®
A Guide to Keeping Your LTI® Tool Working Without Third-Party Cookies
LTI® tools are usually displayed in an iFrame inside the LMS. That makes for a seamless interface, and it means every cookie your tool sets is a third-party cookie.
A third-party cookie is one set by a domain other than the one in the address bar. Inside an LMS iFrame, the address bar belongs to the LMS, so your tool's cookies are third-party cookies.
Browsers have been restricting these for years, on different schedules. Safari blocks them by default and has since 2020. Firefox partitions them by default, so a cookie set inside one site's iFrame is not readable inside another's. Chrome announced a full deprecation, delayed it repeatedly, and then reversed it — third-party cookies still work there by default, but not in Incognito mode, and any user can turn them off.
The practical consequence has not changed with the announcements: you cannot rely on a third-party cookie surviving an LTI® launch. Some of your users are already in a browser that drops it.
For why this breaks LTI® specifically, rather than websites in general, see Why LTI® launches break without third-party cookies.
Does LTIAAS Require Cookies?
No. LTIAAS has set no cookies at all since February 2022.
Instead, we store the temporary launch state in the browser's localStorage, and we verify the write by reading it back before continuing. If that write fails or does not read back, and the LMS supports it, we fall back to LTI® Platform Storage (video) — a protocol that asks the LMS to hold the value for us, so nothing is stored on your tool's origin at all.
We try localStorage first because not every LMS implements Platform Storage yet.
Everything after the launch is keyed off the ltik, which arrives as a query parameter on the URL rather than in any browser storage. That is why an LTIAAS launch survives being opened in a new tab.
What Action Is Needed Of Me?
To understand if third-party Cookie blocking will affect your LTI® tool, there are a couple of tools available to help:
Using Google Chrome, enable third-party cookie blocking.
This is a quick and easy pass/fail test. If the LTI® launch process works and you are able to use your tool as a teacher/student, you are probably not reliant on third-party cookies.
Install the Google Chrome Privacy Sandbox Analysis Tool (PSAT) into Google Chrome.
Using PSAT, you can get more insight on what Cookies your LTI® tool is reliant on and how to resolve them.
When testing third-party Cookie blocking, make sure to test the deep-linking flow (if you tool uses it) as well as a launch within an iframe.
Oh No, My Tool Is Broken! How Do I Fix It?
There are many ways to resolve this issue. Here are several that we recommend to our customers:
Options That Modify or Remove Cookies
Leverage Browser sessionStorage:
If you have full control over your authentication system, you can use the web browser's sessionStorage API to store session information instead of within a Cookie. This requires JavaScript to set and retrieve the session information within the front-end.
Using a JWT Query Parameter:
Upon an LTI® launch, LTIAAS send a query parameter called
ltik. This is a JWT that your tool uses to login/authenticate the user. After you authenticate the user, you can append your login JWT as a query parameter to your front-end so it is always accessible. The JWT can then be sent from your front-end to your back-end every time you make a request the requires authentication.Using Partitioned Cookies:
If you control the cookie being set, add
SameSite=None; Secure; Partitioned;to it. This is Cookies Having Independent Partitioned State (CHIPS), and it keeps the cookie working inside the iFrame by scoping it to the LMS that embedded you.Check current support before relying on it — it is well supported in Chromium browsers and less so elsewhere, and a partitioned cookie is still a cookie, so a user who has blocked them entirely will still not get one. Treat it as a fix for most of your users rather than all of them.
When Changing Cookies Is Not Possible
You might not be able to change your tool's use of Cookies. That's OK, there is still an option. Simply open the tool in a new browser tab, instead of an iFrame. There's a couple of ways to do this:
- Ask the LMS to always open your tool in a new tab. Most LMSes support this, but sometimes admin mistakes are made and your tool doesn't open in a new tab. So option 2 is still recommended.
- If you detect that your tool is within an iFrame, give the user a button that opens your tool in a new tab. Here are some example JavaScript/React code snippets.
// JavaScript function to detect if the page is loaded in an iFrame
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
// ReactJs Example Code
// When page loads, check if we are in an Iframe, and ask the user to open in a new Tab
{inIframe() === true &&
<button onClick={() => {window.open(window.location.href);}}>Open In New Tab</button>
}
This makes the LTI® integration feel a little less magical, but it will allow your tool to continue to work, which is the most important thing.
Specifically for Deep-Linking content selection: Simply opening your tool in a new tab will break the integration with most LMSes.
Handling Deep-Linking in a New Tab
Opening your tool in a new tab after a basic LTI® launch is totally fine to do. But, if you need to have your tool opened in a new tab for deep-linking, great care must be taken to not break the Deep-Linking process. Most LMSes use the iFrame postMessage API to send deep-linking data from the tool iFrame to the LMS parent window. So if you leave the iFrame, the LMS will attempt to post a message to a parent window that no longer exists, breaking deep-linking with the LMS. Here's a couple options to handle this.
Don't require a login for deep-linking:
For many tools, user login is only required for a normal tool launch and getting deep-linking data can simply be authenticated with a one-off call to the LTIAAS idtoken API with no user session created. This will allow you to keep the deep-linking flow within an iFrame.
Use Polling or WebSockets:
If you must open the deep-linking view in a new tab, you must keep some communication between the new tab and the existing iFrame so the the deep-linking process can be completed back in the iFrame after the content selection is completed in the new tab. There are a couple of ways to handle this.
Use iFrame Polling: This is a simple and robust solution. After the new tab is opened, the iFrame polls your tool's back-end to see whether the content selection has completed in the new tab. We recommend polling once a second which creates an unnoticeable lag in most cases. Once the user completes the content selection in the new tab, the new tab stores the selection item in your tool's back-end database. We recommend using the LTIAAS-provided ltik as a database key to guarantee that no other user sessions could get mistakenly consumed by the iFrame. After the iFrame polls successfully, it then posts the form to the document body and finishes the deep-linking process.
Use WebSockets: Similar to using Polling above, you can use WebSockets to make a connection between the iFrame and new tab. This is not recommended because WebSockets require more effort to ensure their reliability. But if your application already uses WebSockets, they could be reused for this purpose.
Getting Help
There's a lot of information to digest here, and picking the right approach depends on how your tool handles sessions. LTIAAS is here to help our customers work through it.
