我如何通过JWT的lambda函数与Salesforce连接

时间:2019-03-27 10:39:36

标签: node.js lambda salesforce jsforce

我想知道如何通过lambda函数与salesforce联系。

现在,我尝试创建Lambda应用程序,该应用程序在客户在我们的EC网站中注册帐户时记录客户的信息。
数据流如下:

  1. 在EC网站上注册帐户信息
  2. EC站点将数据存储到dynamoDB
  3. 要将记录插入dynamoDB触发器中以调用lambda函数
  4. 在lambda函数中,与salesforce连接并创建自定义记录

我已经使用原始的userid / password + token完成了上述操作。
但是由于安全原因,这对我们不利。

我有一个文档,描述了我们可以使用JWT对其进行身份验证。
但是,如果使用JWT,则需要准备证明文件和密钥。

我有2个实现这些目标的计划,但这可能还不够。

A。使用Amazon Certificate Manager B.在我的本地PC上颁发证书和密钥,并将其存储到参数存储区

使用ACM似乎很好,但是此服务不允许下载密钥,因此我认为它无法使用。 在本地计算机上发布2个文件似乎也可以实现,但是我不知道lambda函数中使用了哪个域,并且存在使证书过期的风险。

无论如何,我想在没有任何安全风险的情况下向Salesforce插入自定义记录。

以下代码是lambda函数之一,可以执行以上具有安全风险的事情。

import * as lambda from 'aws-lambda';
import * as jsforce from 'jsforce';

export const register: lambda.DynamoDBStreamHandler = async (event: lambda.DynamoDBStreamEvent, _context: lambda.Context): Promise<any> => {
  const connection: jsforce.Connection = await connect();
  const entities : Array<object> = convert(event.Records);

  await insertRecords(connection, entities);
}

function convert(records: lambda.DynamoDBRecord[]): Array<object>{
  let ret: Array<object> = [];
  records.forEach(record => {
    if(record.eventName !== 'INSERT'){
      return;
    }
    const row = record.dynamodb.NewImage;
    const id: string = row.customer_id.N;
    const name: string = row.name.S;
    const tel : string = row.tel.S;
    console.log(`convert: ${id}, ${name}, ${tel}`);
    const sfdcAccount:object = {
      AccountNumber: id,
      Name: name,
      Phone: tel
    }
    ret.push(sfdcAccount);
  });

  return ret;
}

async function connect():Promise<jsforce.Connection> {
  console.log('try to connect'); 
  const conn: jsforce.Connection = new jsforce.Connection({
    loginUrl: 'https://login.salesforce.com/'
  });
  const user = 'xxx@yyy.zzz';
  const pwd = 'password';
  const token = 'issued token';
  await conn.login(user, pwd+token, function (err, userInfo) {
    if (err) {
      console.log(err);
      throw Error(err.message);
    }
    console.log(`token: ${conn.accessToken}`);
    console.log(`url:   ${conn.instanceUrl}`);
    console.log(`id :   ${userInfo.id}`);
  });
  return conn;
}

async function insertRecords(con: jsforce.Connection, entities: Array<object> ): Promise<any>{
  await con.sobject("Account").create(entities, function (err, rets){
    if(err) {
      console.log(`error : ${err}`);
    }else{
      console.log(`ret : ${rets}`);
    }
  });
}

我想更改connect()方法,以消除这种安全风险:

async function connect():Promise<jsforce.Connection> {
  console.log('try to connect'); 
  const claim = {
    iss: ISSUER,
    aud: AUDIENCE,
    sub: 'xxx@yyy.zzz',
    exp: String(Date.now() + 3 * 60 * 1000)
  };
  const cert = undefined; //getting certification from somewhere
  const token = jwt.sign(claim, cert, {algorithm: 'RS256'});

  await request({
    method: 'POST',
    url: TOKEN_ENDPOINT_URL, 
    form: {
      grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
      assertion: token
    }
  }, function (err, response, body){
    const ret = JSON.parse(body);
    const conn = new jsforce.Connection({
      accessToken: ret.access_token, 
      instanceUrl: ret.instance_url
    });
    return conn;
  });
}

有人解决吗?

0 个答案:

没有答案