pozil / salesforce-react-integration

Sample integration project between Salesforce and a React.js application
Apache License 2.0
68 stars 62 forks source link

Getting Error while starting Server. "Error: secret option required for sessions" #2

Closed developervishaldhawan closed 5 years ago

developervishaldhawan commented 6 years ago

Hi,

I am new to express and node. I have Configured and instantiated the client.

Here is my server.js code so far:

// Load .env configuration file
require('dotenv').config();

// 3rd party dependencies
const httpClient = require("request"),
  path = require('path'),
  express = require('express'),
  session = require('express-session'),
  SalesforceClient = require('salesforce-node-client');

// Settings for Salesforce connection
const sfdcConfig = {
  // OAuth authentication domain
  // For production or a Developer Edition (DE) use
  domain: 'https://login.salesforce.com',
  // For a sandbox use
  //domain : 'https://test.salesforce.com',

  // URL called by Salesforce after authorization and used to extract an authorization code.
  // This should point to your app and match the value configured in your App in SFDC setup)
  callbackUrl: 'http://localhost:8080/auth/callback',

  // Set of secret keys that allow your app to authenticate with Salesforce
  // These values are retrieved from your App configuration in SFDC setup.
  // NEVER share them with a client.
  consumerKey: 'myConsumerKey',
  consumerSecret: 'myConsumerSecret',

  // Salesforce API version
  apiVersion: '41.0'
};

// Instantiate Salesforce client with .env configuration
const sfdc = new SalesforceClient(sfdcConfig);

// Setup HTTP server
const app = express();
const port = process.env.PORT || 8080;
app.set('port', port);

// Enable server-side sessions
app.use(session({
  secret: process.env.sessionSecretKey,
  cookie: { secure: process.env.isHttps === 'true' },
  resave: false,
  saveUninitialized: false
}));

// Serve HTML pages under root directory
app.use('/', express.static(path.join(__dirname, '../public')));

function getSession(request, response) {
  const session = request.session;
  if (typeof session['sfdcAuth'] === 'undefined') {
    response.status(401).send('No active session');
    return null;
  }
  return session;
}

// Login endpoint
app.get("/auth/login", function(request, response) {
  // Redirect to Salesforce login/authorization page
  var uri = sfdc.auth.getAuthorizationUrl({scope: 'api'});
  return response.redirect(uri);
});

// Login callback endpoint (only called by Force.com)
app.get('/auth/callback', function(request, response) {
    if (!request.query.code) {
      response.status(500).send('Failed to get authorization code from server callback.');
      return;
    }

    // Authenticate with Force.com via OAuth
    sfdc.auth.authenticate({
        'code': request.query.code
    }, function(error, payload) {
        if (error) {
          console.log('Force.com authentication error: '+ JSON.stringify(error));
          response.status(500).json(error);
          return;
        }

        // Store oauth session data in server (never expose it directly to client)
        request.session.sfdcAuth = payload;
        // Redirect to app main page
        return response.redirect('/index.html');
    });
});

// Logout endpoint
app.get('/auth/logout', function(request, response) {
  const session = getSession(request, response);
  if (session == null)
    return;

  // Revoke OAuth token
  sfdc.auth.revoke({token: session.sfdcAuth.access_token}, function(error) {
    if (error) {
      console.error('Force.com OAuth revoke error: '+ JSON.stringify(error));
      response.status(500).json(error);
      return;
    }

    // Destroy server-side session
    session.destroy(function(error) {
      if (error)
        console.error('Force.com session destruction error: '+ JSON.stringify(error));
    });

    // Redirect to app main page
    return response.redirect('/index.html');
  });
});

// Endpoint for retrieving currently connected user
app.get('/auth/whoami', function(request, response) {
  const session = getSession(request, response);
  if (session == null)
    return;

  // Request user info from Force.com API
  sfdc.data.getLoggedUser(session.sfdcAuth, function (error, userData) {
    if (error) {
      console.log('Force.com identity API error: '+ JSON.stringify(error));
      response.status(500).json(error);
      return;
    }
    // Return user data
    response.send(userData);
    return;
  });
});

// Endpoint for performing a SOQL query on Force.com
app.get('/query', function(request, response) {
  const session = getSession(request, response);
  if (session == null)
    return;

  if (!request.query.q) {
    response.status(400).send('Missing query parameter.');
    return;
  }

  const query = encodeURI(request.query.q);
  const apiRequestOptions = sfdc.data.createDataRequest(session.sfdcAuth, 'query?q='+ query);

  httpClient.get(apiRequestOptions, function (error, payload) {
    if (error) {
      console.error('Force.com data API error: '+ JSON.stringify(error));
      response.status(500).json(error);
      return;
    }
    else {
      response.send(payload.body);
      return;
    }
  });
});

app.listen(app.get('port'), function() {
  console.log('Server started: http://localhost:' + app.get('port') + '/');
});

When starting the app using npm start and opening the URL: "http://localhost:8080/" in my browser, i am getting below error:

Error: secret option required for sessions
    at session (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express-session\index.js:199:12)
    at Layer.handle [as handle_request] (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\index.js:317:13)
    at C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\index.js:335:12)
    at next (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\index.js:275:10)
    at expressInit (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\middleware\init.js:40:5)
    at Layer.handle [as handle_request] (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\index.js:317:13)
    at C:\salesforce-react-integration-master\salesforce-react-integration-master\node_modules\express\lib\router\index.js:284:7

Please help if any thing missing in the above code.

Thanks & Regards, Vishal

developervishaldhawan commented 6 years ago

I am able to solve above issue. But salesforce returning callback URL and below JSON:

{"code":"ETIMEDOUT","errno":"ETIMEDOUT","syscall":"connect","address":"101.53.161.2","port":443}

Its not redirecting me to Index.html

pozil commented 6 years ago

Hi Vishal, this is happening because you have set the callback URL with an IP address that is not visible to Salesforce. Have you tried to use localhost like in my code sample?

developervishaldhawan commented 6 years ago

Hi Philippe,

Thanks for responding. Above issue is solved, it was an issue with proxy URL.

The issue which currently i am facing is with Heroku deployment. I deployed app using Git integrated with VS code. When opening app with heroku provided url i am getting an application error. Below is the log related to this issue:

2018-04-18T07:31:03.290610+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2018-04-18T07_31_03_262Z-debug.log
2018-04-18T07:31:12.142261+00:00 heroku[web.1]: Starting process with command `npm run build-n-stasrt`
2018-04-18T07:31:14.935289+00:00 heroku[web.1]: Process exited with status 1
2018-04-18T07:31:14.945036+00:00 heroku[web.1]: State changed from starting to crashed
2018-04-18T07:31:14.842451+00:00 app[web.1]: npm ERR! missing script: build-n-stasrt
2018-04-18T07:31:14.854406+00:00 app[web.1]: 
2018-04-18T07:31:14.854410+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2018-04-18T07:31:14.854412+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2018-04-18T07_31_14_844Z-debug.log
2018-04-18T07:31:47.300461+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/auth/login" host=myAppName.herokuapp.com request_id=78f70a40-76a2-45eb-8936-ede2b5aa8783 fwd="121.244.147.149" dyno= connect= service= status=503 bytes= protocol=https
2018-04-18T07:31:47.737836+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=myAppName.herokuapp.com request_id=79427cf1-ed6a-42e8-bf8b-50b1f1d185d4 fwd="121.244.147.149" dyno= connect= service= status=503 bytes= protocol=https

I have changed callback URL in salesforce connected App and in server.js:

Other than this any other value i have to change in the code for production/heroku deployment?

Thanks

pozil commented 6 years ago

Looks like you are not using the correct NPM start script (you have a typo): missing script: build-n-stasrt

developervishaldhawan commented 6 years ago

Oh i see. But similar kind of issue after updating proc file.

2018-04-18T10:12:11.794638+00:00 app[web.1]: npm ERR! 
2018-04-18T10:12:11.794795+00:00 app[web.1]: npm ERR! Failed at the myAppName@0.1.0 build-n-start script.
2018-04-18T10:12:11.794948+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2018-04-18T10:12:11.798752+00:00 app[web.1]: 
2018-04-18T10:12:11.798995+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2018-04-18T10:12:11.799239+00:00 app[web.1]: npm ERR!     /app/.npm/_logs/2018-04-18T10_12_11_796Z-debug.log
2018-04-18T10:12:11.885411+00:00 heroku[web.1]: State changed from starting to crashed
2018-04-18T10:12:11.862550+00:00 heroku[web.1]: Process exited with status 1
2018-04-18T10:16:51.115469+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=myAppName.herokuapp.com request_id=a2a58dd8-4be2-41bb-acf7-e6c4aca39bd0 fwd="125.21.165.152" dyno= connect= service= status=503 bytes= protocol=https
2018-04-18T10:16:51.670436+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=myAppName.herokuapp.com request_id=30e5fa54-5621-4978-961c-7ecb8e4351b4 fwd="125.21.165.152" dyno= connect= service= status=503 bytes= protocol=https
2018-04-18T10:20:41.156747+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/auth/login" host=myAppName.herokuapp.com request_id=f928bf4f-3a20-408d-adbd-7463b1c00c9a fwd="121.244.147.149" dyno= connect= service= status=503 bytes= protocol=https
2018-04-18T10:20:41.671455+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=myAppName.herokuapp.com request_id=96f8990d-1ac4-48c7-b929-f4fcbb5f2854 fwd="121.244.147.149" dyno= connect= service= status=503 bytes= protocol=https

Is that build issue? I am using "react-scripts build"

Below is my scripts section from package.json

"scripts": {
    "start": "node server/server.js",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "build-n-start": "npm run build && npm run start",
    "preinstall": "rm -fr public/assets",
    "postinstall": "cp -r node_modules/@salesforce-ux/design-system/assets public"
  }

Please suggest if any change required.

Thanks & Regards, Vishal Dhawan

pozil commented 6 years ago

Looks like your issue happens in the build-n-start script. Don't you have logs before that?

Also, could you try running just the build script to isolate the issue?

pozil commented 5 years ago

Closing stale issue.