12 Sep 2019

Using Implicit Grant for 3-legged authentication

Sometimes you just want your website to be hosted on a webserver that you do not have direct access to, i.e. you cannot add your own server-side code to help with 3-legged authenticationhttps://forge.autodesk.com/en/docs/oauth/v2/tutorials/get-3-legged-token/

We have a sample on 3-legged authentication using implicit grant here, but I thought it could be nice to have a full sample that consists of a single html page and also calls other API's - in this case just the users/@me endpoint to get info about the user. See the result in the above picture

index.html:

<html>
    <head>
        <title>3-legged implicit grant test</title>
    </head>
    <body onload="MyStuff.onLoad()">
        <script>
            var MyStuff = {
                "access_token": "",
                "LogIn": ["Log In", "Logged In"],
                "onLoad": function () {
                    console.log("onLoad")

                    var url = new URL(window.location.href.replace('#', '?'))

                    var query_string = url.search

                    var search_params = new URLSearchParams(query_string)

                    MyStuff.access_token = search_params.get('access_token')

                    let logInButton = document.getElementById("LogIn")
                    logInButton.innerText = (MyStuff.access_token) ? MyStuff.LogIn[1] : MyStuff.LogIn[0]

                    console.log(MyStuff.access_token)
                },
                "getUserInfo": function () {
                    console.log("getUserInfo")

                    if (MyStuff.access_token === "") 
                        return

                    fetch('https://developer.api.autodesk.com/userprofile/v1/users/@me', { 
                        headers: {
                            'Authorization': `Bearer ${MyStuff.access_token}`
                        }
                    })
                    .then(res => res.text())
                    .then(data => {
                        let json = JSON.parse(data)
                        let pretty = JSON.stringify(json, null, 2)
                        MyStuff.showInfo(pretty)
                        console.log(data)
                    })
                },
                "logIn": function () {
                    console.log("logIn")

                    let clientId = "<your app's client id>" 
                    let scopes = "data:read+bucket:read"
                    let redirectUri = encodeURI("http://localhost:5500")
                    window.open(`https://developer.api.autodesk.com/authentication/v1/authorize` +
                        `?response_type=token&client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scopes}`, "_self")
                },
                "showInfo": function (text) {
                    let logInButton = document.getElementById("Info")
                    logInButton.value = text
                }
            }
        </script>
        <button id="LogIn" onclick="MyStuff.logIn()">Log In</button>
        <br /><br />
        <button id="GetUserInfo" onclick="MyStuff.getUserInfo()">Get User Info</button>  
        <br /><br />
        <textarea id="Info"></textarea>      
    </body>
</html>

In order to test the code, you have to start a server to serve your page. If you are using VS Code then you can simply use the Live Server plugin for it

Live Server plugin

I'm sure other development environments have similar options.

Related Article