Node.js 如何在前端和后端位于不同端口时获得DocuSign嵌入式签名
我正在进行一个项目,以集成DocuSign嵌入签名仪式功能。我的前端是Angular 6(端口:4200),它运行在与后端NodeJS(端口:3000)不同的端口上 前端将调用后端(RESTAPI)来生成PDF文件。完成后,它将触发重定向到embeddedsigning路由,以连接到DocuSign以获取PDF文件签名 成功生成PDF文件后,将触发Node.js 如何在前端和后端位于不同端口时获得DocuSign嵌入式签名,node.js,docusignapi,Node.js,Docusignapi,我正在进行一个项目,以集成DocuSign嵌入签名仪式功能。我的前端是Angular 6(端口:4200),它运行在与后端NodeJS(端口:3000)不同的端口上 前端将调用后端(RESTAPI)来生成PDF文件。完成后,它将触发重定向到embeddedsigning路由,以连接到DocuSign以获取PDF文件签名 成功生成PDF文件后,将触发'/api/docusign/signing'路由(请参阅下面的代码) 回调似乎不起作用,因为它将响应发送回前端,这不是我的意图。需要回调,以便将PD
'/api/docusign/signing'
路由(请参阅下面的代码)
回调似乎不起作用,因为它将响应发送回前端,这不是我的意图。需要回调,以便将PDF上载到DocuSign并触发DocuSign以提示签名者签名文档。完成后,后端将更新数据库,然后再传回前端
我仍然在学习和体验NodeJS,我不知道如何去做。任何有任何想法或经历的人都可以分享如何去做。谢谢你的帮助。谢谢
docusign routes.js
module.exports = (app) => {
app.get('/api/docusign/auth', docuSignController.authenticate);
app.get('/api/docusign/callback', [docuSignController.dsLoginCB1, docuSignController.dsLoginCB2]);
app.get('/api/docusign/signing', docuSignController.requireDocuSignToken,
docuSignController.embeddedsigning);
}
exports.authenticate = (req, res, next) => {
passport.authenticate('docusign')(req, res, next);
};
exports.requireDocuSignToken = (req, res, next) => {
let tokenBufferMin = 30;
let now = moment();
console.log('requireDocuSignToken');
if (tokenBufferMin && req.docusign && req.docusign.accessToken &&
now.add(tokenBufferMin, 'm').isBefore(req.docusign.expires)) {
console.log('\nUsing existing access token');
next();
} else {
console.log('\nGet a new access token');
res.redirect('http://localhost:3000/api/docusign/auth');
}
};
exports.dsLoginCB1 = (req, res, next) => {
passport.authenticate('docusign', {failureRedirect: '/api/docusign/auth'})(req, res, next);
};
exports.dsLoginCB2 = (req, res, next) => {
res.redirect('/api/docusign/signing');
}
exports.embeddedsigning = (req, res, next) => {
...
}
docuSignController.js
module.exports = (app) => {
app.get('/api/docusign/auth', docuSignController.authenticate);
app.get('/api/docusign/callback', [docuSignController.dsLoginCB1, docuSignController.dsLoginCB2]);
app.get('/api/docusign/signing', docuSignController.requireDocuSignToken,
docuSignController.embeddedsigning);
}
exports.authenticate = (req, res, next) => {
passport.authenticate('docusign')(req, res, next);
};
exports.requireDocuSignToken = (req, res, next) => {
let tokenBufferMin = 30;
let now = moment();
console.log('requireDocuSignToken');
if (tokenBufferMin && req.docusign && req.docusign.accessToken &&
now.add(tokenBufferMin, 'm').isBefore(req.docusign.expires)) {
console.log('\nUsing existing access token');
next();
} else {
console.log('\nGet a new access token');
res.redirect('http://localhost:3000/api/docusign/auth');
}
};
exports.dsLoginCB1 = (req, res, next) => {
passport.authenticate('docusign', {failureRedirect: '/api/docusign/auth'})(req, res, next);
};
exports.dsLoginCB2 = (req, res, next) => {
res.redirect('/api/docusign/signing');
}
exports.embeddedsigning = (req, res, next) => {
...
}
问题中显示的代码摘录没有显示
embeddedsigning
方法
该方法应该做什么:
returnUrl
参数可以是角度前端的URL,也可以是节点后端的URL。这取决于你的应用程序架构。两者都应该有效url
元素 res.redirect(results.url);
下面是即将发布的代码示例中的一个示例:
// Step 3. create the recipient view, the Signing Ceremony
let viewRequest = makeRecipientViewRequest(envelopeArgs)
, createRecipientViewP = req.dsAuthCodeGrant.makePromise(
envelopesApi, 'createRecipientView')
;
// call the CreateRecipientView API
results = null; // reset
try {
results = await createRecipientViewP(accountId, envelopeId,
{recipientViewRequest: viewRequest});
}
catch (error) {
let errorBody = error && error.response && error.response.body
// we can pull the DocuSign error code and message from the response body
, errorCode = errorBody && errorBody.errorCode
, errorMessage = errorBody && errorBody.message
res.render('pages/error', {err: error, errorCode: errorCode, errorMessage: errorMessage});
}
if (!results) {return}
// Step 4. Redirect the user to the Signing Ceremony
// Don't use an iFrame!
// State can be stored/recovered using the framework's session or a
// query parameter on the returnUrl (see the makeRecipientViewRequest method)
res.redirect(results.url);
以下是makeRecipientViewRequest
以下是makePromise代码:
const{promisify}=require('util');
//看http://2ality.com/2017/05/util-promisify.html
/**
*返回一个promise方法{methodName}\u promise,这是一个
*方法参数的授权版本。
*如果promise方法不存在,则创建它。
*它通过父对象的附件进行缓存。
*@函数
*@param obj具有方法methodName的对象
*@param methodName现有方法的字符串名称
*@returns{promise}方法名的承诺版本。
*/
DSAuthCodeGrant.prototype.makePromise=函数_makePromise(obj,methodName){
让promiseName=methodName+'u promise';
如果(!(obj中的承诺人姓名)){
obj[promiseName]=promisify(obj[methodName]).bind(obj)
}
返回对象[承诺人姓名]
}
补充
(关于评论,请参见下文。)
我认为您应该从后端使用passport。这样,passport/DocuSign重定向将转到您的后端
由于您试图从前端做太多工作,所以您遇到了CORS问题
如果你想编写更多的纯前端DocuSign应用程序,你可以,但你需要一个私人CORS网关。查看我的博客帖子,然后
注意:对于前端应用程序,您必须使用隐式授权,而不是授权码授权。感谢您的回复。问题是passport.authenticate使用此URL重定向到我的前端localhost:4200。。。当浏览器控制台指示错误时,飞行前的响应无效(重定向)。它无法访问/api/docusign/callback。当我使用postman测试时,嵌入的签名功能正在工作。@user10153962,我已添加到我答案的底部。欢迎使用StackOverflow!请投票选出所有有用的答案,包括对他人问题的答案。请检查/接受您自己问题的最佳答案!
const {promisify} = require('util');
// See http://2ality.com/2017/05/util-promisify.html
/**
* Returns a promise method, {methodName}_promise, that is a
* promisfied version of the method parameter.
* The promise method is created if it doesn't already exist.
* It is cached via attachment to the parent object.
* @function
* @param obj An object that has method methodName
* @param methodName The string name of the existing method
* @returns {promise} a promise version of the <tt>methodName</tt>.
*/
DSAuthCodeGrant.prototype.makePromise = function _makePromise(obj, methodName){
let promiseName = methodName + '_promise';
if (!(promiseName in obj)) {
obj[promiseName] = promisify(obj[methodName]).bind(obj)
}
return obj[promiseName]
}