Validation

    All requests made by Plivo to your server URLs consist of a X-Plivo-Signature-V3 and X-Plivo-Signature-V3-Nonce HTTP headers. To validate the request and to verify that the request to your server has originated from Plivo, you must generate the signature at your end and compare it with X-Plivo-Signature-V3 parameter in the HTTP header and check whether they are identical. Read more about signature validation here on the Developers Portal.

    Methods to compute and verify X-Plivo-Signature-V3 are available in the latest SDKs. Please select the programming language of your choice and switch to the latest version to see how to use these methods.

    Arguments

    uri string

    The callback which you want to validate. This uri can be answer_url, url (message callback), message_url, callback_url, action_url, or hangup_url.

    nonce string

    You can get this from the relevant event details posted to your callback.

    X-Plivo-Signature-V3 or X-Plivo-Signature-Ma-V3 string

    You can get this from the relevant event details posted to your callback.

    auth_token string

    Your account auth-token which you can get from your Plivo dashboard.

    Response

      True
    

    Example Request

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    from flask import Flask, request, make_response, url_for
    import plivo
    from urllib.parse import urlparse, parse_qs
    from plivo import utils
    from plivo import plivoxml
    
    app = Flask(__name__)
    
    @app.route('/speak/', methods=['GET', 'POST'])
    def validate_signature():
        signature = request.headers.get('X-Plivo-Signature-V3', 'signature')
        nonce = request.headers.get('X-Plivo-Signature-V3-Nonce', '12345')
        url = url_for('validate_signature', _external=True)
        auth_token = "your_auth_token"
        method = request.method
        if method == 'GET':
            valid = plivo.utils.validate_v3_signature(
                method, url, nonce, auth_token, signature)
        else:
            params = request.get_json()
            valid = plivo.utils.validate_v3_signature(
                method, url, nonce, auth_token, signature, params)
        print(valid)
        r = plivoxml.ResponseElement()
        speak_params = {
            'loop': '3'
        }
        r.add(plivoxml.SpeakElement("Hello, from Plivo", **speak_params))
        response = make_response(r.to_string())
        response.headers["Content-type"] = "text/xml"
        print(r.to_string())
        return response
    
    
    if __name__ == "__main__":
        app.run(host='0.0.0.0', debug=True)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    require 'sinatra'
    require 'rubygems'
    require 'plivo'
    include Plivo
    include Plivo::XML
    
    get '/speak/' do
    	auth_token = "Your_Auth_Token"
    	signature = headers.fetch("X-Plivo-Signature-V3", "signature")
    	nonce = headers.fetch("X-Plivo-Signature-V3-Nonce", "12345")
    	url = request.url
    	method = "GET"
    	output = Plivo::Utils.valid_signatureV3?(url, nonce, signature, auth_token, method)
    	puts output
    
    	response = Response.new
    	response.addSpeak("Hello, Welcome to Plivo")
    	xml = PlivoXML.new(response)
    	content_type 'text/xml'
    	return xml.to_s
    end
    
    post '/speak/' do
    	auth_token = "your_auth_token"
    	signature = headers.fetch("X-Plivo-Signature-V3", "signature")
    	nonce = headers.fetch("X-Plivo-Signature-V3-Nonce", "12345")
    	url = request.url
    	method = "POST"
    	output = Plivo::Utils.valid_signatureV3?(url, nonce, signature, auth_token, method, params)
    	puts output
    
    	response = Response.new
    	response.addSpeak("Hello, Welcome to Plivo")
    	xml = PlivoXML.new(response)
    	content_type 'text/xml'
    	return xml.to_s
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    let express = require('express');
    let app = express();
    app.set('port', (process.env.PORT || 5000));
    app.use(express.static(__dirname + '/public'));
    
    app.all('/speak/', function (request, response) {
        let headers = request.headers;
        console.log(headers);
        let signature = request["X-Plivo-Signature-V3"];
        let nonce = request["X-Plivo-Signature-V3-Nonce"];
        if (!signature) {
            signature = "signature";
        }
        if (!nonce) {
            nonce = "12345";
        }
        let url = request.url;
        let auth_token = "your_auth_token";
        console.log(signature, nonce);
        let method = request.method;
        let validate;
        if (method == "GET") {
            validate = plivo.validateV3Signature(method, url, nonce, auth_token, signature);
        } else {
            let params = request.body;
            validate = plivo.validateV3Signature(method, url, nonce, auth_token, signature, params);
        }
        console.log(validate);
    
        let r = plivo.Response();
        r.addSpeak("Hello from Plivo");
        console.log(r.toXML());
    
        response.set({
            'Content-Type': 'text/xml'
        });
        response.end(r.toXML());
    });
    
    app.listen(app.get('port'), function () {
        console.log('Node app is running on port', app.get('port'));
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    <?php
    require 'vendor/autoload.php';
    use Plivo\Exceptions\PlivoValidationException;
    use Plivo\Util\v3SignatureValidation;
    use Plivo\XML\Response;
    
    if (preg_match('/speak/', $_SERVER["REQUEST_URI"])) {
        $auth_token = "your_auth_token";
        $signature = @$_SERVER["X-Plivo-Signature-V3"] ?: 'signature';
        $nonce = @$_SERVER["X-Plivo-Signature-V3-Nonce"] ?: 'nonce';
        $url = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
        $method = $_SERVER['REQUEST_METHOD'];
        $SVUtil = new v3SignatureValidation();
        if ($method == "GET") {
            try {
                $valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature);
            } catch (PlivoValidationException $e) {
                echo("error");
            }
        } else {
            $body = file_get_contents("php://input");
            $params = json_decode($body, true);
            try {
                $valid = $SVUtil->validateV3Signature($method, $url, $nonce, $auth_token, $signature, $params);
            } catch (PlivoValidationException $e) {
                echo("error");
            }
        }
        echo $valid;
        $body = 'Hi, Calling from Plivo';
        $attributes = array(
            'loop' => 3,
        );
        $r = new Response();
        $r->addSpeak($body, $attributes);
        echo($r->toXML());
    } else {
        echo "<p>Welcome to Plivo</p>";
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    
    package plivoexample;
    
    import java.io.IOException;
    import java.net.URLDecoder;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.plivo.helper.exception.PlivoException;
    import com.plivo.helper.xml.elements.Message;
    import com.plivo.helper.xml.elements.PlivoResponse;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    
    import com.plivo.helper.util.*;
    
    public class validateSignature extends HttpServlet {
      private static final long serialVersionUID = 1L;
      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        String auth_token = "your_auth_token";
        String signature = req.getHeader("X-Plivo-Signature-V3");
        String nonce = req.getHeader("X-Plivo-Signature-V3-Nonce");
        String url = req.getRequestURL().toString();
        String method = req.getMethod();
    
        if(method == "GET") {
          try {
            Boolean isValid = Utils.validateSignatureV3(url, nonce, signature, auth_token, method);
            System.out.println("Valid : " + isValid);
          } catch (PlivoException e) {
            e.printStackTrace();
          }
        }
        else{
          try {
            Map<String, String> params = req.getParameterMap();
            Boolean isValid = Utils.validateSignatureV3(url, nonce, signature, auth_token, method, params);
            System.out.println("Valid : " + isValid);
          } catch (PlivoException e) {
            e.printStackTrace();
          }
        }
    
        PlivoResponse response = new PlivoResponse();
        Speak spk = new Speak("Hello, Welcome to Plivo");
    
        try {
          response.append(spk);
          System.out.println(response.toXML());
          resp.addHeader("Content-Type", "text/xml");
          resp.getWriter().print(response.toXML());
        } catch (PlivoException e) {
          e.printStackTrace();
        }
      }
    
      public static void main(String[] args) throws Exception {
        String port = System.getenv("PORT");
        if(port==null)
          port ="8000";
        Server server = new Server(Integer.valueOf(port));
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);
        context.addServlet(new ServletHolder(new  validateSignature()),"/speak");
        server.start();
        server.join();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using RestSharp;
    using Plivo.XML;
    using Plivo;
    using Nancy;
    
    namespace plivo_dotnet_app
    {
        public sealed class Program : NancyModule
        {
            public Program()
            {
                Get("/speak/", x =>
                {
                    string signature = Request.Headers["X-Plivo-Signature-V3"].ToString();
                    string nonce = Request.Headers["X-Plivo-Signature-V3_Nonce"].ToString();
                    string auth_token = "your_auth_token";
                    string method = Request.Method;
                    string url = Request.Url;
                    bool valid;
                    Dictionary<string, string> parameters = new Dictionary<string, string>();
                    valid = Plivo.Utilities.XPlivoSignatureV3.VerifySignature(url, nonce, signature, auth_token, method);
                    Debug.WriteLine("Valid : " + valid);
    
                    Plivo.XML.Response resp = new Plivo.XML.Response();
                    resp.AddSpeak("Hello, Welcome to Plivo", parameters);
                    Debug.WriteLine(resp.ToString());
    
                    var output = resp.ToString();
                    var res = (Nancy.Response) output;
                    res.ContentType = "text/xml";
                    return res;
                });
    
                Post<Response>("/speak/", x =>
                {
                    string signature = Request.Headers["X-Plivo-Signature-V3"].ToString();
                    string nonce = Request.Headers["X-Plivo-Signature-V3_Nonce"].ToString();
                    string auth_token = "your_auth_token";
                    string method = Request.Method;
                    string url = Request.Url;
                    bool valid;
                    Dictionary<string, string> parameters = new Dictionary<string, string>();
                    parameters = Request.Form;
                    valid = Plivo.Utilities.XPlivoSignatureV3.VerifySignature(url, nonce, signature, auth_token, method, parameters);
                    Debug.WriteLine("Valid : " + valid);
    
                    Plivo.XML.Response resp = new Plivo.XML.Response();
                    resp.AddSpeak("Hello, Welcome to Plivo", parameters);
                    Debug.WriteLine(resp.ToString());
    
                    var output = resp.ToString();
                    var res = (Nancy.Response) output;
                    res.ContentType = "text/xml";
                    return res;
                });
            }
            
            static void Main(string[] args)
            {
                var p = new Program();
            }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    
    package main
    
    import (
    	"encoding/json"
    	"fmt"
    	"io/ioutil"
    	"net/http"
    	"reflect"
    	"unsafe"
    
    	"github.com/plivo/plivo-go"
    	"github.com/plivo/plivo-go/xml"
    	"github.com/sirupsen/logrus"
    )
    
    type Message struct {
    	Id   string `json:"id"`
    	Name string `json:"name"`
    }
    
    func BytesToString(b []byte) string {
    	bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    	sh := reflect.StringHeader{bh.Data, bh.Len}
    	return *(*string)(unsafe.Pointer(&sh))
    }
    
    func speak(w http.ResponseWriter, request *http.Request) {
    	url := request.Host + request.RequestURI
    	signature := request.Header.Get("X-Plivo-Signature-V3")
    	nonce := request.Header.Get("X-Plivo-Signature-V3-Nonce")
    	method := request.Method
    	authToken := "your_auth_token"
    	var valid bool
    	if method == "GET" {
    		valid = plivo.ValidateSignatureV3(url, nonce, method, signature, authToken)
    	} else {
    		parameters := make(map[string]string)
    		b, err := ioutil.ReadAll(request.Body)
    		defer request.Body.Close()
    		if err != nil {
    			http.Error(w, err.Error(), 500)
    			return
    		}
    
    		var msg Message
    		err = json.Unmarshal(b, &msg)
    		if err != nil {
    			http.Error(w, err.Error(), 500)
    			return
    		}
    
    		var inInterface map[string]interface{}
    		inrec, _ := json.Marshal(msg)
    		json.Unmarshal(inrec, &inInterface)
    		for field, val := range inInterface {
    			parameters[field] = val.(string)
    		}
    
    		w.Header().Set("content-type", "text/xml")
    		valid = plivo.ValidateSignatureV3(url, nonce, method, signature, authToken, parameters)
    	}
    	logrus.Info(valid)
    	response := xml.ResponseElement{
    		Contents: []interface{}{
    			new(xml.SpeakElement).
    				SetContents("Go Green, Go Plivo."),
    		},
    	}
    	fmt.Fprintf(w, response.String())
    }
    
    func main() {
    	http.HandleFunc("/speak/", speak)
    	http.ListenAndServe(":5000", nil)
    }