Posting grades with React app

Community Member

Hi. I'm attempting to create a basic React app with an Express server and integrate this app as a third party LTI app in Canvas. I'm currently able to send a grade to the gradebook using the ims-lti library linked here.

Here's a simplified version of my app and what I want to do. In my Express server, I have the following: 


const path = require('path')
const port = process.env.PORT || 3000;

const express = require('express')
const app = express()
const lms = require('./src/assets/lms.js')
global.sess = {};

// Used to parse request data that sent from web pages in JSON format
app.use(express.urlencoded({extended: false}))

app.use(express.static(path.join(__dirname, 'build')));
app.get(/[a-z]+/, function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});'/application', function(req, res) {
  var provider = global.sess.provider;

  if(provider.outcome_service) {
    (err, result) => {
})'/launch', lms.handleLaunch);
These functions, including handleLaunch, are part of my Canvas integration.
const lti = require('ims-lti');
// MemoryStore shouldn't be used in production. Timestamps must be valid within a 5 minute grace period.
const nonceStore = new lti.Stores.MemoryStore();

// secrets should be stored securely in a production app
const secrets = {
  demo: 'xzc342AScx',
  demo2: 'dh43fvL-ew'

const getSecret = (consumerKey, callback) => {
  const secret = secrets[consumerKey];
  if (secret) {
    return callback(null, secret);

  let err = new Error(`Unknown consumer ${consumerKey}`);
  err.status = 403;

  return callback(err);

exports.handleLaunch = (req, res, next) => {
 if (!req.body) {
    let err = new Error('Expected a body');
    err.status = 400;
    return next(err);

  const consumerKey = req.body.oauth_consumer_key;
  if (!consumerKey) {
    let err = new Error('Expected a consumer');
    err.status = 422;
    return next(err);

  getSecret(consumerKey, (err, consumerSecret) => {
    if (err) {
      return next(err);

    const provider = new lti.Provider(consumerKey, consumerSecret, nonceStore, lti.HMAC_SHA1);

    provider.valid_request(req, req.body, (err, isValid) => {
      if (err) {
        return next(err);

      if (isValid) {
        if(provider.outcome_service) {
          global.sess.provider = provider;

          return res.redirect('/login');
        return res.send(`It looks like this LTI wasn't launched as an assignment, \
        or you are trying to take it as a teacher rather than as a student.`);

      } else {
        return next(err);

Here's a link to the Github repository that I based my Canvas integration off of.


And finally, here is my React page where I allow the user to input a grade.

import React from 'react'
import { withRouter } from 'react-router-dom';

class LoginPage extends React.Component {
    constructor() {
        this.state = {
            score: 0.000

    submitForm(e) {

        fetch('/application', {
            method: 'POST',
            body: JSON.stringify(this.state),
            headers: {
                'content-Type': 'application/json'
        }).then(function (response) {
            return response.json()
        }).then(function (body) {


    render() {
        return (
                    <form onSubmit={this.submitForm.bind(this)}>
                            onChange={e => this.setState({ score: })}>

                        <button type="submit">Begin</button>

export default withRouter(LoginPage);
I want to know if there is a way I can retain the provider data I create in my handleLaunch function without using a global session variable in my'/application') function. I know Node can use request sessions, including storing sessions in a database but I am not sure how to make them work in this case.

Any insights on my issue would be greatly appreciated.