{"id":18544406,"url":"https://github.com/instructure/rack-lti","last_synced_at":"2026-04-02T18:49:37.889Z","repository":{"id":7994309,"uuid":"9401194","full_name":"instructure/rack-lti","owner":"instructure","description":"Rack middleware supporting LTI (http://www.imsglobal.org/toolsinteroperability2.cfm) integration.","archived":false,"fork":false,"pushed_at":"2018-03-15T15:20:43.000Z","size":41,"stargazers_count":21,"open_issues_count":0,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-12-20T15:16:24.537Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/instructure.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-04-12T18:41:56.000Z","updated_at":"2021-03-30T09:24:52.000Z","dependencies_parsed_at":"2022-08-28T07:51:21.896Z","dependency_job_id":null,"html_url":"https://github.com/instructure/rack-lti","commit_stats":null,"previous_names":["zachpendleton/rack-lti"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/instructure/rack-lti","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instructure%2Frack-lti","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instructure%2Frack-lti/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instructure%2Frack-lti/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instructure%2Frack-lti/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/instructure","download_url":"https://codeload.github.com/instructure/rack-lti/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instructure%2Frack-lti/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31213708,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-30T15:24:02.938Z","status":"ssl_error","status_checked_at":"2026-03-30T15:23:44.804Z","response_time":138,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T20:16:27.444Z","updated_at":"2026-04-02T18:49:37.868Z","avatar_url":"https://github.com/instructure.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Rack::LTI\n\n[![Build Status](https://travis-ci.org/zachpendleton/rack-lti.png)](https://travis-ci.org/zachpendleton/rack-lti)\n\nRack::LTI exposes LTI launch and config URLs in your Rack application, handling\nauthorization, storing launch parameters, and generating config information for\nconsumers.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'rack-lti'\n\n## Usage\n\nRack::LTI should work with any Rack-based app. This means Rails 3.x and\nSinatra, and probably whatever wonky framework you happen to be using.\n\nRack::LTI is tested on MRI Ruby 1.9 and 2.0, and the 1.9 branches of JRuby\nand Rubinius. It will not work on any flavor of 1.8; upgrade already.\n\n### Rails 3\n\nAdd Rack::LTI to your `config/application.rb`:\n\n```ruby\nclass Application \u003c Rails::Application\n  config.middleware.use Rack::LTI,\n    consumer_key:    -\u003e(key, consumer_id) { 'key' },\n    consumer_secret: -\u003e(key, consumer_id) { 'secret' }\n\n    app_path:    '/',\n    config_path: '/lti/config.xml',\n    launch_path: '/lti/launch',\n    redirect: true,\n\n    title:       'My LTI App',\n    description: 'My LTI App description',\n\n    nonce_validator: -\u003e(nonce) { !FakeNonceStore.include?(nonce) },\n    success: -\u003e(lti_params, request, response) {\n      request.session['launch_params'] = lti_params\n      response.headers['X-Custom-Header'] = 'value'\n    },\n\n    time_limit: 60*60,\n    future_time_limit: 60,\n\n    extensions: {\n      'canvas.instructure.com' =\u003e {\n        course_navigation: {\n          default: 'enabled',\n          text: 'My LTI App'\n        }\n      }\n    },\n\n    custom_params: {\n      preferred_name: 'El Tigre Chino'\n    }\nend\n```\n\n### Sinatra\n\nAdd Rack::LTI to your app:\n\n```ruby\nclass Application \u003c Sinatra::Base\n  use Rack::LTI,\n    consumer_key:    'my_key',\n    consumer_secret: 'my_secret',\n\n    app_path:    '/',\n    config_path: '/lti/config.xml',\n    launch_path: '/lti/launch',\n    redirect: true,\n\n    title:       'My LTI App',\n    description: 'My LTI App description',\n\n    nonce_validator: -\u003e(nonce) { !FakeNonceStore.include?(nonce) },\n    success: -\u003e(lti_params, request, response) {\n      request.session['launch_params'] = lti_params\n      response.headers['X-Custom-Header'] = 'value'\n    },\n\n    time_limit: 60*60,\n    future_time_limit: 60\n\n    extensions: {\n      'canvas.instructure.com' =\u003e {\n        course_navigation: {\n          default: 'enabled',\n          text: 'My LTI App'\n        }\n      }\n    },\n\n    custom_params: {\n      preferred_name: 'El Tigre Chino'\n    }\nend\n```\n\n## Configuration\n\nRack::LTI takes either a configuration hash or block at initialization. Allowed\nvalues are:\n\n  * `consumer_key` The consumer_key to check against the key given at launch.\n    This value can be a string or a lambda. If a lambda, it is passed the key\n    used by the consumer as well as their tool_consumer_instance_guid.\n  * `consumer_secret` The consumer_secret to check against the secret given at\n    launch. Like the consumer key, this value can be a string or a lambda. If a\n    lambda, it is passed the key and tool_consumer_instance_guid of the\n    consumer.\n  * `app_path` The path to redirect to on a successful launch. This should be\n    the main page of your application. Defaults to '/'.\n  * `config_path` The path to serve LTI config XML from. Defaults to\n    '/lti/config.xml'.\n  * `launch_path` The path to receive LTI launch requests at. Defaults to\n    '/lti/launch'.\n  * `redirect` If true, redirect to the `app_path`. If false, pass the launch\n    request through to the application. If false, app_path is not used. Defaults\n    to true.\n  * `title` The title of your LTI application.\n  * `description` The description of your LTI application.\n  * `nonce_validator` A lambda used to validate the current request's nonce.\n    It is passed the nonce to verify. If not provided, all nonces are allowed.\n  * `time_limit` The past time limit, inclusive and in seconds, to consider requests\n    valid within.  If not passed, the default is 3600 seconds (one hour).\n  * `future_time_limit` The future time limit, inclusive and in seconds, to consider\n    requests valid within.  If not passed, all future timestamps are accepted as valid.\n  * `success` A lambda called on successful launch. It is passed the launch\n    params as a hash, the Rack Request, and the Rack Response. Can be used to\n    cache params for the current user, find the current user, etc. By default,\n    the launch params are stored in the 'launch_params' key of the session.\n  * `extensions` A hash of extension information to include with the config.\n    Format is platform -\u003e option -\u003e properties. See usage examples above for\n    more detail.\n  * `custom_params` A hash of custom parameters to accept from the client. See\n    usage examples above for more detail.\n\n## About LTI\n\nInterested in learning more about LTI? Here are some links to get you started:\n\n  * [Introduction to LTI](http://www.imsglobal.org/toolsinteroperability2.cfm)\n  * [1.1.1 Implementation Guide](http://www.imsglobal.org/LTI/v1p1p1/ltiIMGv1p1p1.html)\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstructure%2Frack-lti","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finstructure%2Frack-lti","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstructure%2Frack-lti/lists"}