Node.js
This example provides a very simple partner application template based on Node.js. It helps you to understand the basic steps regarding application integration and how our authentication process works. It uses jsonwebtoken for verifying/signing JWTs and request-promise-native for requests.
Setup
Your package.json
might look like this:
{
"name": "nodejs-example",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"jsonwebtoken": "8.5.1",
"request": "2.34.0",
"request-promise-native": "1.0.7"
}
}
JWT signature verification
In order to verify our JWT's signature based on our stages you will need to download these public key files and put them beside your package.json
:
365FarmNet_Connect-API_public_key_development.pem
365FarmNet_Connect-API_public_key_production.pem
Code
Create a file index.js
and put this code into it:
const http = require('http');
const url = require('url');
const fs = require('fs');
const jwt = require('jsonwebtoken');
const rp = require('request-promise-native');
// developer partner credentials
const partner_id = '5726c2cf-143b-4834-aa54-24a1c1516a48';
const partner_secret = 'trsL26xTtFXgPHBJE8n4ZrN6R7fWfLrK';
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/html' });
const connect_token_jwt = getConnectTokenJwtFromUrl(req.url);
if (connect_token_jwt == null) {
res.end('No Connect-Token found, pass "jwt" as URL query parameter!');
return;
}
const connect_token = jwt.decode(connect_token_jwt);
const api_base = connect_token && connect_token['fn-ext'] && connect_token['fn-ext']['apiBase'] || null;
if (api_base == null) {
res.end(`The decoded Connect-Token seems strange '${connect_token}'. 'apiBase' expected!`);
return;
}
const stage = api_base === 'https://connect.365farmnet.com' || api_base === 'https://pp-connect.365farmnet.com' ? 'production' : 'development';
try {
verifyConnectTokenJwt(connect_token_jwt, stage);
} catch (e) {
res.end('The Connect-Token is invalid: ' + JSON.stringify(e));
return;
}
console.log('Your Connect-Token\'s content is: ' + JSON.stringify(connect_token));
const partner_token_jwt = createPartnerTokenJwt(connect_token_jwt);
if (partner_token_jwt == null) {
res.end('Your Partner-Token could not be created. Check logs!');
return;
}
getCompanyFromApi(api_base, partner_token_jwt).then(data => {
res.end('OK: ' + JSON.stringify(data));
}).catch(err => res.end('Error fetching data: ' + JSON.stringify(err)));
}).listen(3000);
function getConnectTokenJwtFromUrl(req_url) {
const query = url.parse(req_url, true).query;
return query.jwt || null;
}
function verifyConnectTokenJwt(connect_token_jwt, stage) {
const public_key = fs.readFileSync('365FarmNet_Connect-API_public_key_' + stage + '.pem');
return jwt.verify(connect_token_jwt, public_key, { clockTolerance: 10 }) || null;
}
function createPartnerTokenJwt(connect_token_jwt) {
const payload = {
con: connect_token_jwt,
iss: partner_id
};
const options = {
expiresIn: '1d',
header: {
ver: '0.1',
type: 'partner'
}
};
try {
return jwt.sign(payload, partner_secret, options) || null;
} catch (e) {
console.log(e);
}
}
function getCompanyFromApi(api_base, partner_token_jwt) {
return rp({
uri: `${api_base}/connect/v1/company`,
headers: {
Authorization: `Bearer ${partner_token_jwt}`
}
});
}
Run
Open your terminal, install the dependencies and start the application using either node
or npm start
. This will spawn a server listening for calls on port 3000. You can open your browser, navigate to localhost:3000 and should see No Connect-Token found, pass "jwt" as URL query parameter!
.
Then navigate to our developer environment, register and set the URL to http://localhost:3000/. Since the example uses our developer credentials
it should work out of the box and give your account information.