Skip to Content
Technical Articles
Author's profile photo Nicolai Schoenteich

SAP Tech Bytes: Verify JSON Web Tokens (JWT) from the SAP Approuter – Cloud Foundry Basics #5

This SAP Tech Byte is about how to use the SAP Approuter in combination with another Node.js based application and set up proper authentication between the two using JSON Web Tokens. In this scenario, we benefit from SAP Approuter capabilities such as easy connections to destinations and the XSUAA service (Authorization and Trust Management Service), while also having the freedom to build any Node.js application we want (for example a server-side rendering NuxtJS application).

The source code for this blog post can be found at

Note: I will use the terms “validate” and “verify” interchangeably in this blog post.



As already discovered in the previous blog posts, the SAP Approuter is usually used to route users to static resources in the form of local directories and destinations. In doing so, the Approuter abstracts the authorization and token flow (think magic) – making these concepts really easy to implement and more secure. The Approuter itself is a Node.js based application that contains an xs-app.json file describing its routing behavior. In the most common scenario, this xs-app.json file points to a local directory or a remote repository containing a static web page (HTML, CSS, JavaScript). But what if we want to forward requests to a second server application that is separately deployed and reachable via a URL? As far as the Approuter is concerned, this is not a problem at all. We simply define a new route in the xs-app.json that points to a destination, and that destination points to the URL of the second application. But we do have a problem: How do we prevent users from accessing this second application directly? In theory, users could find this URL and access it – bypassing the Approuter and its authorization flow – not good! This is where the validating JSON Web Tokens comes into play.

This is essentially what we want to do:


In this scenario, the second application (on the right) is a server-side rendering NuxtJS application. This application has one key obligation, and that is validating the JWT that it receives from users. Let’s take a closer look at the individual parts of our architecture.


SAP Approuter

Let’s first look at the left half of the architecture.

The SAP Approuter is a pretty simple Node.js based application that acts as the main entry point of our architecture. It redirects users to the Authorization and Trust Management Service (XSUAA), where users login and receive a JSON Web Token (JWT), before being redirected back to the Approuter. The Approuter then forwards all request to a destination. This is all configured via the xs-app.json file:

	"authenticationMethod": "route",
	"routes": [
        	"source": "^(.*)",
        	"target": "$1",
        	"destination": "nuxt",
        	"authenticationType": "xsuaa"


The “nuxt” destination is added to the Approuter via its environment variables. The destination points to the URL of the NuxtJS application and is configured with forwardAuthToken = true to forward the user’s authorization token (JWT). This ensures that the JWT will be included in every request that goes from the Approuter to the NuxtJS application (in the req.header.authorization object):

{"name":"nuxt", "url":"", "forwardAuthToken": true}


The XSUAA service instance is created using the Cloud Foundry CLI. This has to be done before deploying the Approuter, as the Approuter requires the XSUAA service instance during deployment.


NuxtJS Application

Let’s now look at the right half of the architecture.

Now this is where things get interesting. As already mentioned previously, we have to prevent users from bypassing the Approuter and accessing the NuxtJS application directly. After all, we want all users to first authenticate against the XSUAA instance before being able to interact with our application. The NuxtJS framework has a very convenient way of handling middleware (see named middleware), as you can simply add files to the middleware/ directory that will always get executed first when accessing the application. So by creating a middleware/auth.js file and referencing it in the nuxt.config.js we have the perfect place to check if a valid JWT is present in the request header.

To validate a JWT, we can use a combination of Node.js packages provided by SAP. First, we use @sap/xsenv to load the XSUAA environment our NuxtJS application is bound to via an application binding in Cloud Foundry (see its manifest.yaml). An application binding essentially means that service instance credentials are stored in the environment variables of an application, which is why the corresponding method is fittingly called xsenv.loadEnv(). Now that we have the XSUAA environment, we can use the second package @sap/xssec to create a security context and pass it the token we received via the req.header.authorization object from the Approuter. The xssec.createSecurityContext() method sends a request to the XSUAA instance that validates it. This is a so called “online validation”. If there is no token or the token is invalid, an unauthorized error is returned. If a valid token is present, the middleware is exited without errors and the user gets to the UI of the application. This what the whole middleware/auth.js file looks like:

var xssec = require('@sap/xssec')
var xsenv = require('@sap/xsenv')

export default function (context) {

	const {
	} = context

	const unauthorized = () => {
		return error({
			statusCode: 401,
			message: "401 - Unauthorized"

	if (!req.headers.authorization) {
	} else {
		// splitting "Bearer " from the header
		const token = req.headers.authorization.split(" ")[1]
			xsenv.getServices({ xsuaa: { tag: 'xsuaa' } }).xsuaa,
			function (error, securityContext, tokenInfo) {
				if (error) {


There is also the possibility to validate the token offline with a package like jsonwebtoken (see method jwt.verify()). In this case, the public key of the XSUAA instance is used validate the signature of a token via an algorithm – all done locally without an external request (offline).


Developing Locally

The described architecture requires application bindings of the Approuter and the NuxtJS application to the XSUAA instance. You might be wondering how this can be achieved locally. As already stated earlier, an application binding is essentially achieved by storing the service instance credentials in the environment variable of an application. We can do exactly that to run the scenario locally.


First, we have to deploy the whole architecture once, so that Cloud Foundry generates the environment variables. To do that, run the following command in the approuter/ directory:

sh && cf push


Once the Approuter is deployed, run the following command in the nuxt/ directory:

npm install && npm run build && cf push


Now we can get the environment variable from the deployed Approuter:

cf env approuter-nuxt


Copy the output (only the VCAP_SERVICES object is required) in a new default-env.json in the approuter/ directory. Also add the required destination information and the port environment variable to make sure our Approuter runs on the port that is whitelisted for the XSUAA instance. The file should look like this:

    "PORT": 5001,
    "destinations": [
            "name": "nuxt",
            "url": "",
            "forwardAuthToken": true
        "xsuaa": [ ... ]


We can now continue with the NuxtJS application and get its environment variables:

cf env nuxt


Again, copy the output (only the VCAP_SERVICES object is required) in a new default-env.json – but this time in the nuxt/ directory. The file should look like this:

        "xsuaa": [ ... ]


Now we can start both applications in separate terminals. Run the following command in the approuter/ directory:

npm start


Run the following command (in a separate terminal) in the nuxt/ directory:

npm run dev


Voila, we now have set-up both application to run just like they do in the cloud and can start developing. You should notice you get redirected to the XSUAA instance when accessing the Approuter at http://localhost:5001.

I hope you enjoyed this blog post. Hopefully you learned a little something about how to verify JSON Web Tokens from the SAP Approuter or an XSUAA instance more generally.

Feel free to reach out in case you have any questions.

Stay tuned for more blog posts covering the basics of Cloud Foundry.








SAP Tech Bytes is an initiative to bring you bite-sized information on all manner of topics, in video and written format. Enjoy!




Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Sreehari V Pillai
      Sreehari V Pillai

      Hi . thanks for this.

      I did a test as this.
      I generated access token . Then I am trying to verify the generated jwt using the below code piece .It always goes to "Invalid signature" error. Any clue

      const fs = require("fs");
      const jwt = require("jsonwebtoken");
      var cert = fs.readFileSync('public.pem','utf8');
      var token = '<mytoken>';
      jwt.verify(token, cert, {
          algorithms: ['RS256']
      }, function (err, decoded,) {
          //goes to error says "invalid signature"


      pem file is a copy paste from "verification key" from xsuaa credentials. 


      Author's profile photo Nicolai Schoenteich
      Nicolai Schoenteich
      Blog Post Author

      What exactly do you pass in the cert object? Do you have a public key from your xsuaa that you could pass instead? Also, I don't think you have to explicitly specify the algorithm - at least I didn't have to do it using an xsuaa on SAP BTP, Cloud Foundry environment.

      Author's profile photo Sreehari V Pillai
      Sreehari V Pillai

      cert object is a string that looks like this, which I copied from xsuaa credentials. I expect ( if I understand correctly ) , using the xsuaa , system generated a token (which I can decode in ) . Now using the public key in xsuaa , I must be able to validate it . I use "jsonwebtoken" standard npm package for this.
      I tried with and without providing algorithm . I am sure I am missing something here. I replaced \n in the

      Posted as a question in community



      Author's profile photo Nicolai Schoenteich
      Nicolai Schoenteich
      Blog Post Author

      Hmm, maybe keep the \n and also make sure to not include "Bearer " in the token?

      Author's profile photo Nicolai Schoenteich
      Nicolai Schoenteich
      Blog Post Author

      I can see you figured it out in the separate thread. Nice!

      Author's profile photo Sreehari V Pillai
      Sreehari V Pillai

      it was with the multi tenancy thing . I am still unsure how to get this verified in mtx mode


      thanks mate.

      Author's profile photo Sreehari V Pillai
      Sreehari V Pillai

      regarding algorithm , I see that '@sap/xssec' uses the below piece of code to verify the toke, which has algorithm mentioned.


          this.verify = function (getKeyCBOrValue, cb) {
              return jwt.verify(encoded,
                      algorithms: ['RS256'] //XSUAA currently only allow/generate RS256
                  function (err) {
                      errobj = err;
                      if (err) {
                          errobj.statuscode = 401;
                      return cb(err, this);


      Author's profile photo Nicolai Schoenteich
      Nicolai Schoenteich
      Blog Post Author

      Very interesting! Good find.