1
votes

Building a basic application where users can find Service Providers using MEAN Stack, and after negotiations are over, agreements are auto generated and have to be signed by both parties. Got Stuck on generation of JWT Token for authentication. Steps I followed are:

  1. Generate a url for obtaining consent from user and pass it to frontend. Users will be redirected and permissions can be granted from there.
var url = "https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature&client_id=42017946-xxxx-xxxx-xxxx-81b0ca97dc9a&redirect_uri=http://localhost:4200/authorization_code/callback";

res.status(200).json({
    status: 1,
    message: 'Fetched',
    value: url
});
  1. After successful redirection with code in URL, API call is made to backend for the generation of JWT token.

  2. Token is generated as follows:

var jwt = require('jsonwebtoken');
var privateKey = fs.readFileSync(require('path').resolve(__dirname, '../../src/environments/docusign'));

const header = {
    "alg": "RS256",
    "typ": "JWT"
};

const payload = { 
    iss: '42017946-xxxx-xxxx-a5cd-xxxxxx', 
    sub: '123456', 
    iat: Math.floor(+new Date() / 1000), 
    aud: "account-d.docusign.com", 
    scope: "signature" 
};

var token = jwt.sign(payload, privateKey, { algorithm: 'RS256', header: header });

Private key used above is from docusign admin panel. iss -> Integration key against my app. sub -> user id in the drop down of user symbol in admin panel

  1. Obtain the access token
const axios = require('axios');

axios.post('https://account-d.docusign.com/oauth/token', 
    { 
        grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", 
        assertion: token 
    })
    .then(resposne => {
        console.log(response);
    })
    .catch(err => {
        if (err.response) {
            console.log(err);
        } else if (err.request) {} 
        else {}
    })

But I am constantly getting error: { error: 'invalid_grant', error_description: 'no_valid_keys_or_signatures' }

1

1 Answers

0
votes

I would suggest using the node.JS SDK or npm package and using the build-it JWT method to authenticate. The code would look like this: (click here for GitHub example)

DsJwtAuth.prototype.getToken = async function _getToken() {
    // Data used
    // dsConfig.dsClientId
    // dsConfig.impersonatedUserGuid
    // dsConfig.privateKey
    // dsConfig.dsOauthServer
    const jwtLifeSec = 10 * 60, // requested lifetime for the JWT is 10 min
        scopes = "signature", // impersonation scope is implied due to use of JWT grant
        dsApi = new docusign.ApiClient();
    dsApi.setOAuthBasePath(dsConfig.dsOauthServer.replace('https://', '')); // it should be domain only.
    const results = await dsApi.requestJWTUserToken(dsConfig.dsClientId,
        dsConfig.impersonatedUserGuid, scopes, rsaKey,
        jwtLifeSec);

    const expiresAt = moment().add(results.body.expires_in, 's').subtract(tokenReplaceMin, 'm');
    this.accessToken = results.body.access_token;
    this._tokenExpiration = expiresAt;
    return {
        accessToken: results.body.access_token,
        tokenExpirationTimestamp: expiresAt
    };