Connecting javascript SinglePageApplications to Turnkey (SPA)
No edit summary
No edit summary
Line 50: Line 50:
         }
         }


     }
     }</pre>To handle cors and Authentication in the model I follow the stipulated pattern and add this:
[[File:2021-02-28 23h24 21.png|none|thumb|780x780px]]
 
The methods are implemented like this:
 
GetAllowOriging:
if KnownExternalApp.allinstances->exists(x|(x.Origin=org) and (x.IsOk)) then 
<nowiki> </nowiki> true -- we want to allow this app to call us
else 
<nowiki> </nowiki> false
endif
AcceptAndTransformUserName:
if KnownExternalApp.allinstances->exists(x|(x.Audience=audience) and (x.IsOk)) then 
<nowiki> </nowiki> user -- we want to allow all users from this domain if they exists in our domain
else 
<nowiki> </nowiki> <nowiki>''</nowiki>
endif
 
<pre>
</pre>
</pre>

Revision as of 22:28, 28 February 2021

This page was created by Hans.karlsen@mdriven.net on 2021-02-28. Last edited by Stephanie@mdriven.net on 2025-01-21.

In order to connect SPA's built with pure-javascript or React or Angular or Vue or anthing else we must address these needs:

  1. Cors - allow foreign apps to query our Turnkey server
  2. Authentication - allow foreign apps to acquire a jwt from somewhere (Oauth host) and we want to check it and possibly accept it
  3. Stay logged in - with a cookie after initial authentication

To show this we can use the Microsoft SPA example from here : https://docs.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-javascript-auth-code

If you follow all the instructions there you soon have a SPA application that logs in with Azure AD - and gives you idToken that are in jwt format (really jws as they are signed).

Once you have this example - follow the lead and add another button, just like the readMail and seeProfile buttons from the sample:

function readTurnkey() {
    getTokenPopup(loginRequest)
        .then(response => {

            const headers = new Headers();
            const bearer = `Bearer ${response.idToken}`;
            const endpoint ='http://localhost:5052/TurnkeyRest/Get?command=RestExample'
            headers.append("Authorization", bearer);

            const options = {
                method: "GET",
                headers: headers
            };

            console.log('request made to Turnkey API at: ' + new Date().toString());

            fetch(endpoint, options)
                .then(response => response.json())
                .then(response => updateUI(response, endpoint))
                .catch(error => { console.log(error); });



        }).catch(error => {
            console.error(error);
        });
}

What we do here is to acquire a new idToken, and sending it to a Turnkey Rest api that in this case is at http://localhost:5052/TurnkeyRest/Get?command=RestExample

The json we get from this call is sent to updateUI where we do this:

   else {
        // turnkey data:
        try {
            profileDiv.innerHTML = JSON.stringify(data);
        }
        catch (err) {
            profileDiv.innerHTML = data.toString();
        }

    }

To handle cors and Authentication in the model I follow the stipulated pattern and add this:

2021-02-28 23h24 21.png

The methods are implemented like this:

GetAllowOriging:

if KnownExternalApp.allinstances->exists(x|(x.Origin=org) and (x.IsOk)) then  
  true -- we want to allow this app to call us 
else  
  false 
endif 

AcceptAndTransformUserName: 
if KnownExternalApp.allinstances->exists(x|(x.Audience=audience) and (x.IsOk)) then  
  user -- we want to allow all users from this domain if they exists in our domain 
else  
  '' 
endif
MDriven Chat

How would you like to chat today?

Setting up your conversation…

This may take a few moments