Writing LTI Stuff
This page goes over the basics of creating an app that leverages LTI. There's a lot of great links at the bottom that may help out, but it's probably a good idea to at least read the intro first to get a feel for what LTI does exactly.
Introduction
Identity assertion is a one-way "handshake" coming from the learning platform (consumer) to the app (provider).
The main thing with LTI is the identity assertion. LTI is a way for one system (the tool consumer, typically an LMS) to send a user to another system (the tool provider, some service that integrates with the LMS -- sorry, I know the names are confusing. I've tried using colors to help make things clearer, but that may just make it worse...) in a trusted way. The most common reason for the trust assertion is to allow the user to be automatically signed in and directed to a specific course or module when the provider renders content.
Tools (providers) are launched from within the learning platform (consumer) in an iframe so they feel like a native part of the platform.
The consumer and provider have some predefined relationship via a consumer key and shared secret that are used to sign any messages passed between systems. All messages are signed with an OAuth signature that can be verified by either party. For the most part information only travels one way, from the consumer to the provider.
The identity assertion happens through an HTTP POST request from the consumer to the provider. The POST request must happen in the user's browser, which means it needs to be launched by submitting a form. Most of the time the form is submitted via JavaScript to an iframe rendered on a page within the consumer, so the user doesn't have an extra step when trying to launch an app.
Below are a list of parameters that can be sent as part of the POST request. Some are required, some are optional. Most apps shouldn't need more than the first set of parameters and can probably just ignore the rest.
Building an LTI App
If you want to build an LTI-compliant app or provider then there's really only a couple things you need to worry about: how users can configure your app, how to accept a launch from a consumer, and potentially handling some of the extra goodies LTI makes possible.
App Configuration
App configuration is different for every LMS right
now, but we're working on that. The best way to provide a standard configuration
for your app is by providing a url that returns an xml configuration for your
app. There's a lot of
examples of app
configurations in the Canvas API documentation. Remember, if there's custom
values you want to make sure come across with every user, this is the place
to include them. The only really crucial piece to specify is the url endpoint that will
accept the POST requests, blti:launch_url
.
Typically users will either copy the url to your xml configuration, or copy and paste the configuration itself. Notice that the configuration does not include the consumer key or shared secret. These are account-specific values, and if they were included they'd prevent the xml from being reusable. Admins will still have to enter the key and secret values that a provider gives them into the consumer manually.
App Launch
Once an app is configured, it will be added by one or more instructors into their material as some sort of link or button in the consumer. Any time a student, instructor, administrator, or random internet passersby clicks the link they will be directed to the provider via a signed POST request. It is the provider's responsibility to confirm the signature on the POST request. If the signature is invalid then none of the information should be trusted.
If the signature is valid then you should accept the identity assertion provided by the consumer and log the user in to your service. Many services have their own registration flow, so it's not uncommon to require an additional registration step the first time a user launches your app.
Signatures are generated using the OAuth signing process. Google provides a nice tool for generating OAuth signatures that you can use to test your signing code, although you'll probably save yourself some trouble if you can find a library to do the work for you.
Extras
This page has described the most basic type of LTI integration. There's a number of other things you can do on top of this, including passing scores from the provider back to the gradebook of the
consumer, or adding buttons to the rich editor in the consumer to insert rich content generated or curated by the provider. Check out the extensions demos page or the Canvas API documentation on external tools for more detail on these extensions and how they work.POST Parameters
These are all of the known values that can be passed from the consumer to the provider when a user clicks a link to launch the app.
Most Common Parameters
Parameter | Status | Notes |
---|---|---|
lti_message_type |
required | set to basic-lti-launch-request |
lti_version |
required | set to LTI-1p0 |
resource_link_id |
required |
unique id referencing the link, or "placement", of the app in the
consumer. If an app was added twice
to the same class, each placement would send a different id, and
should be considered a unique "launch". For example, if the
provider were a chat room
app, then each resource_link_id would be a separate
room.
|
user_id |
recommended | unique id referencing the user accessing the app. providers should consider this id an opaque identifier. |
user_image |
optional | if provided, this would be a url to an avatar image for the current user. We recommend that these urls be 50px wide and tall, and don't expire for at least 3 months. |
roles |
recommended |
there's a long list of possible roles, but here's the most common ones:
|
lis_person_name_full |
recommended | Full name of the user accessing the app. This won't be sent if apps are configured to launch users anonymously or with minimal information. |
lis_outcome_service_url |
optional | If this url is passed to the provider then it means the app is authorized to send grade values back to the consumer gradebook for any students that access the app. There's more information available in the Canvas API documentation. |
selection_directive |
optional | If this parameter is passed to the provider then it means the consumer is expecting the provider to return some piece of information such as a url, an html snippet, etc. There's more information available in the Canvas API documentation. |
Additional Parameters
Parameter | Status | Notes |
---|---|---|
lis_person_name_given |
recommended | First name of the user accessing the app. This won't be sent if apps are configured to launch users anonymously or with minimal information. |
lis_person_name_family |
recommended | Last name of the user accessing the app. This won't be sent if apps are configured to launch users anonymously or with minimal information. |
lis_person_contact_email_primary |
recommended | Email address of the user accessing the app. This won't be sent if apps are configured to launch users anonymously or with minimal information. |
resource_link_title |
recommended | name of the link that launched the app |
resource_link_description |
optional | description of the link that launched the app |
context_id |
recommended | unique id of the course from which the user is accessing the app. If a app were added multiple times to the same course, this id would be the same regardless of which link was used to launch the app. |
context_type |
optional | this is the type of context from which the user is accessing the app. If it's provided, this will most likely be CourseSection |
context_title |
recommended | name of the course from which the user is accessing the app |
context_label |
recommended | short name or course code of the course from which the user is accessing the app |
launch_presentation_locale |
recommended | locale (i.e. en-US ) for the user accessing the app |
launch_presentation_document_target |
recommended | if provided, this value will be either (if the app has been launched in a new window) or |
launch_presentation_css_url |
optional | css file that could be included by the provider to help its styling better match the consumer styling. This isn't well-documented, so I typically pretend it doesn't exist. |
launch_presentation_width |
recommended | width of the frame or window in which the app is launched. This is only a starting point, since the frame could change if the user resizes their window. |
launch_presentation_height |
recommended | height of the frame or window in which the app is launched. This is only a starting point, since the frame could change if the user resizes their window. |
launch_presentation_return_url |
recommended |
url to send the user to when they're finished with the provider. The provider can optionally send one of four values as query parameters appended to the url:
|
tool_consumer_info_product_family_code |
recommended | product name for the consumer. This could
be something like moodle , sakai or canvas |
tool_consumer_info_version |
recommended | version number of the consumer product. |
tool_consumer_instance_guid |
strongly recommended | unique id referencing the instance from which the user is accessing the app. This mostly makes sense only in a multi-tenant environment. |
tool_consumer_instance_name |
recommended | name of the instance from which the user is accessing the app. |
tool_consumer_instance_description |
optional | description of the instance from which the user is accessing the app. |
tool_consumer_instance_url |
optional | url of the instance from which the user is accessing the app. |
tool_consumer_instance_contact_email |
recommended | email address of a contact at the instance from which the user is accessing the app. |
custom_* |
optional |
any number of custom values can optionally be sent across. The key
for any custom values should start with custom_ and should
be in snake case. Custom values can optionally be defined on the
consumer side as part of the app configuration
process.
|