Skip to content

Laravel app setup

Chris Pittman edited this page Aug 24, 2023 · 11 revisions

Laravel app setup

The setup to integrate your app with LTI will vary depending on which version of LTI you're using.

General Notes

  • If your app relies on information stored in a session, keep in mind that browser security restrictions can prevent third-party sites from setting a session cookie, and that your app launching from an LMS looks like a third-party site to the browser. For apps that launch in a new window, setting the session.same_site config to 'none' may be sufficient. For apps that launch in an iframe, you may have to take additional steps, or use a non-cookie-based authentication method such as JWTs.

LTI 1.3

LTI 1.3 is the most up-to-date version of the LTI specification, and is the only version which is currently certified by IMS Global.

  • Install this library, using the installation instructions in the README.
  • If your app uses the VerifyCsrfToken middleware (which it does by default), add your LTI routes to the $except array in that middleware:
class VerifyCsrfToken extends Middleware
{
    protected $except = [
        '/lti',
        '/lti/*'
    ];
}
  • Create an 'LTIController' controller in your app.
  • Add two routes to routes/web.php:
Route::any('/lti', [App\Http\Controllers\LtiController::class, 'ltiMessage']);
Route::get('/lti/jwks', [App\Http\Controllers\LtiController::class, 'getJWKS']);
  • Generate an RSA public/private key pair using a tool such as https://cryptotools.net/rsagen. (The config/lti.php file allows you to control where the app loads those keys from.)
  • Add the LtiController::getJWKS function:
    public function getJWKS() {
        $tool = LtiTool::getLtiTool();
        return $tool->getJWKS();
    }
  • Add the LtiController::ltiMessage function:
    public function ltiMessage(Request $request) {
        $tool = LtiTool::getLtiTool();

        $tool->handleRequest();

        if ($tool->getLaunchType() === $tool::LAUNCH_TYPE_LAUNCH) {
            /*
            At this point:
              $tool->platform describes the platform (LMS)
              $tool->context describes the context (course)
              $tool->resourceLink describes the resourceLink (tool placement in course)
              $tool->userResult describes the user.

            Each of these has a getRecordId() function which returns a database primary key.
            Store these keys in a session or in your app's database for later lookup.
            If your app has database tables corresponding to courses, users, etc you can store this primary key in that table.
            */
            
            ... application-launch logic here, which is probably just a redirect to a home page or dashboard of some kind.
            ... The app can use `Tool::getLtiTool()` to get an instance of the Tool object, and can use that object
            ...   to look up contexts, resourceLinks, userResults via the `getXXXXById()` functions, passing in the ID values
            ...   you stored in the session.
            // See https://github.com/celtic-project/LTI-PHP/wiki/Services for how to call LTI services such as the Names and Roles Provisioning Service.
        }

        die("Unknown message type");
    }
  • Create a Platform database entry for each installation of your app, using either:
    • the artisan commands provided by this package - see this repo's wiki for details
    • the methods of the PlatformCreator class in this package
    • or your own custom PHP code, as described in the Celtic docs
  • Install your tool in your LMS. All LTI URLs should be the '/lti' route you created above, except for the JWKS URL, which should be '/lti/jwks'.

LTI 1.0-1.2

⚠️LTI 1.0/1.1/1.2 have been deprecated by IMS Global. New tool implementations should use LTI 1.3. Instructions for earlier versions of LTI are listed here for use by legacy apps that can't update yet.

  • If your app uses the VerifyCsrfToken middleware (which it does by default), add 'lti' to the $except array in that middleware.
  • Add a route to routes/web.php, handling LTI traffic:
Route::post('/lti', [App\Http\Controllers\LtiController::class, 'ltiMessage']);
  • Create a new Controller to respond to this traffic:
use LonghornOpen\LaravelCelticLTI\LtiTool;
use Illuminate\Http\Request;

class LtiController extends Controller
{
    public function ltiMessage(Request $request) {
        $tool = LtiTool::getLtiTool();
        $tool->handleRequest();

        // $tool contains information about the launch - which LMS, course, placement, and user this corresponds to.
        // Store these in your database or session, as appropriate for your app.
        if ($tool->getLaunchType() === $tool::LAUNCH_TYPE_LAUNCH) {
            $consumer_guid = $tool->platform->consumerGuid; // lms
            $lti_context_id = $tool->context->ltiContextId; // course
            $lti_resource_link_id = $tool->resourceLink->ltiResourceLinkId; // placement
            $lti_user_id = $tool->userResult->ltiUserId; // user
            $course_name = $tool->context->title;
            $user_name = $tool->userResult->fullname;
            $user_email = $tool->userResult->email;
            ...
  • Create a Platform database entry for each installation of your app, using either:
    • the artisan commands provided by this package - see this repo's wiki for details
    • the methods of the PlatformCreator class in this package
    • or your own custom PHP code, as described in the Celtic docs
  • Install your tool in your LMS. All LTI URLs should be the '/lti' route you created above.
Clone this wiki locally