Blog
Home/

Send a document from Laravel with JWT Grant authentication

Author Ivan Dinkov
Ivan DinkovSr. Developer Support Advisory Engineer
Summary5 min read

Use the eSignature REST API from our PHP SDK and Laravel to authenticate via JWT Grant and send a document for signature.

    • Requirements
      • Installation
      • Use case
        • Configuration
          • Controller
          • Routes
          • Views
            • Additional resources

            Table of contents

            In this blog post, I will demonstrate how to incorporate Docusign into Laravel while authenticating via OAuth JWT Grant. Integrating eSign is simple thanks to the Docusign eSign PHP Laravel wrapper.

            Requirements

            • PHP 7.4+

            • Developer account

            • Working Laravel application and installed Composer (The guide is using Ubuntu 18.04, Laravel 9.x, and PHP 7.4.)

            Installation

            Docusign has an official Laravel wrapper available on GitHub. The benefit it provides is that it will fetch the latest eSignature PHP SDK client package for you from the package manager, so you will not need to pull it separately. Moreover, this is an official provider by Docusign, so we can provide required support if needed.

            To install the wrapper in your Laravel application, follow the steps in the README documentation.

            Installing through Composer:

            composer require docusign/esign-laravel

            For elevated privileges on Linux, you may need to add sudo.

            After a successful installation, you should see a new docusign directory within your app root vendor directory.

            Add the service provider to the provider's array in config/app.php:

            Docusign\eSign\ESignServiceProvider::class

            Use case

            This example implements the following functions:

            • Allow the user to upload the document and provide the recipient's name and email address.

            • Create an envelope with a composite template.

            • Send the envelope to be signed remotely.

            Note: Please keep in mind that the code in this article is intended for a document containing a SignHere tab. The tab is placed via the anchor string "**signature**" as referenced in the code. You need to insert this string into your document at any place where you want the recipient to sign.

            Configuration

            Connecting to Docusign from Laravel requires some configuration information, which you can store in the Laravel .env file. Add the following lines at the end of your .env file:

            DS_CLIENT_ID="xxxxxx-xxxx-xxxx-xxxxxxx"
            DS_IMPERSONATED_USER_ID="xxxxxx-xxxx-xxxx-xxxxxxx"
            DS_JWT_SCOPE="signature impersonation"
            DS_AUTH_SERVER="account-d.docusign.com"
            DS_ESIGN_URI_SUFFIX="/restapi"
            DS_KEY_PATH="jwt/private.key"
            
            

            Notes:

            • DS_CLIENT_ID: Your application Integration key

            • DS_IMPERSONATED_USER_ID: The User ID of the user to be impersonated

            • DS_DEMO_AUTH_SERVER: The account server we request the token from. (To request token in production replace it with - account.docusign.com)

            You can read more about these values in our JWT guide, How to get an access token with JWT Grant authentication.

            Another important step before generating an access token is to include your private key in Laravel. If you have not yet generated your private key, go to the RSA key pair section of the Configure your App tutorial. To add the private key, create a new directory named jwt under storage and a new file called private.key. Copy and paste your private key without any modifications.

            Controller

            Once you’ve completed the configuration steps, you can move on to create your Controller. The controller name is totally up to you, but keep in mind to include “Controller” in the name; for instance:   

            php artisan make:controller ContractController

            Thanks to Artisan (a command line interface included with Laravel), the command will generate a new controller class for you under the app/Http/Controllers directory.

            Routes

            To have access to your controller, you need to update the routes/web.php file by adding these two lines:

            Route::get('/contract',[ContractController::class,'index']);
            Route::post('/contract',[ContractController::class,'send']);
            
            

            Views

            Views for your controller will be required to gather or show information from/to the user. To separate your views from the rest, create a subdirectory named contract under resources/views. Create two view files for this use case: create.blade.php and response.blade.php, respectively. The “create” view will be used to display the form, and the “response” view will be used to display the outcome of your envelope creation call.

            The ContractController logic is separated into four functions.

            Here’s how each of those functions contributes to the solution.

            Function index

            The index function returns the “create” view that contains the form.

            Function send

            The send function is the core function, containing the main logic. That logic proceeds through four steps:

            Step 1 

            In this step, the function does form validation using Laravel’s built in Validator facade:

            $validator = Validator::make($request->all(), [
                'formFile' => 'required|mimes:doc,docx,pdf|max:2048',
                'name' => 'required|min:3|max:50',
                'email' => 'required|email|max:255'
            ]);        
            if ($validator->fails()) {
                return redirect('/contract')
                ->withErrors($validator)
                ->withInput();
            } 
            
            

            Step 2

            Here, the function instantiates the eSignature API client, sets the correct authentication path, and requests a new token by calling the helper getToken function:

            $apiClient = new ApiClient();
            $apiClient->getOAuth()->setOAuthBasePath(env('DS_AUTH_SERVER')); 
            try{
                $accessToken = $this->getToken($apiClient);
            } catch (\Throwable $th) {
                return back()->withError($th->getMessage())->withInput();
            }
            
            

            Step 3

            In this step, the function requests the authenticated user info. This is one of the most underappreciated API requests; the reason being is that it returns the user account info together with the base_path (including the site where the accounts are located, such as demo, eu, or au).

            $userInfo = $apiClient->getUserInfo($accessToken);
            $accountInfo = $userInfo[0]->getAccounts();
            
            

            Once the function receives the response, it updates the API client base path:

            $apiClient->getConfig()->setHost($accountInfo[0]->getBaseUri() . env('DS_ESIGN_URI_SUFFIX'));

            Step 4

            Here, the function builds the envelope body by using the helper function buildEnvelope:

            $envelopeDefenition = $this->buildEnvelope($request);
            
            

            Then, it makes an API createEnvelope request to Docusign to create the envelope:

            try {            
                 $envelopeApi = new EnvelopesApi($apiClient);
                 $result = $envelopeApi->createEnvelope($accountInfo[0]->getAccountId(), $envelopeDefenition);
                 } catch (\Throwable $th) {
                    return back()->withError($th->getMessage())->withInput();
            }      
            
            

            Function buildEnvelope

            The buildEnvelope function is just a helper function I’ve put in place to separate the envelope build logic.

            Function getToken

            The getToken function reads the content of the private key and makes an API request call to the Docusign account server using the built-in requestJWTUserToken function:

            private function getToken(ApiClient $apiClient) : string{
                    try {
                        $privateKey = file_get_contents(storage_path(env('DS_KEY_PATH')),true);
                        $response = $apiClient->requestJWTUserToken(
                            $ikey = env('DS_CLIENT_ID'),
                            $userId = env('DS_IMPERSONATED_USER_ID'),
                            $key = $privateKey,
                            $scope = env('DS_JWT_SCOPE')
                        );        
                        $token = $response[0];
                        $accessToken = $token->getAccessToken();
                    } catch (\Throwable $th) {
                        throw $th;
                    }    
                    return $accessToken;        
            }
            
            

            You can find the full code for this project on GitHub.

            As you can see from this example, it is very easy to set up and use JWT to authenticate and send documents thanks to Docusign’s PHP SDK client.

            Additional resources

            Author Ivan Dinkov
            Ivan DinkovSr. Developer Support Advisory Engineer
            More posts from this author

            Related posts

            • Accelerating Intelligent Agreement Management with a New “Docusign for Developers”
              Intelligent Agreement Management

              Accelerating Intelligent Agreement Management with a New “Docusign for Developers”

              Dmitri Krakovsky
            • Event Notifications using JSON SIM and HMAC

              Event Notifications using JSON SIM and HMAC

              Author Jonathan Sammons
              Jonathan Sammons
            • Streamline End-to-End Agreement Management with Docusign: A Developer Overview

              Streamline End-to-End Agreement Management with Docusign: A Developer Overview

              Author Larry Jin
              Larry Jin
            Event Notifications using JSON SIM and HMAC

            Event Notifications using JSON SIM and HMAC

            Author Jonathan Sammons
            Jonathan Sammons
            Streamline End-to-End Agreement Management with Docusign: A Developer Overview

            Streamline End-to-End Agreement Management with Docusign: A Developer Overview

            Author Larry Jin
            Larry Jin

            Discover what's new with Docusign IAM or start with eSignature for free

            Explore Docusign IAMTry eSignature for Free
            Person smiling while presenting