Building an application with Speckle Auth

Hello everyone,

I am trying to build an application and i am following this tutorial. I got stuck regarding the accessCode thing:

// This import can go at the top of the file
import store from '@/store'

router.beforeEach(async (to, from, next) => {
  if (to.query.access_code) {
    // If the route contains an access code, exchange it
    try {
      await store.dispatch("exchangeAccessCode", to.query.access_code)
    } catch (err) {
      console.warn("exchange failed", err)
    }
    // Whatever happens, go home.
    next("/")
  }
})

I can see, that this property is used in the POST-request for getting a AuthToken, but i do not understand what the access_code from to.query is. I am using SvelteKit, and i have never used Vue, so there might be something about that… Can someone help me? :slight_smile:

So the pattern with Vue and all events in the router and on the page is that an event has a value.

In the case of router events, the to value is the URL that will contain a token with the access code in the form of:

speckle_server/ _more URL goodness_ / ? access_code=bcdefw3746...

I’m being vague, but in short, to is the inbound address, query is the query parameters and access_code is the magical Auth token.

I’ve only made basic demo apps (typical Hello World ToDo application style), so I may be a bit wrong here (or out of date), but because Svelte has file-based routing, and you can access query parameters directly in the load function or within components using $app/stores.

So, to adapt the given Vue.js logic to SvelteKit, you can detect the presence of an access_code query parameter within a SvelteKit page by using the page store from $app/stores in a load function or directly within your component script. Then, you’ll need to Implement a function to exchange the access_code for an access token.

If anyone in Community has a better handle on Svelte, please step in.

This clarifies where i need to look for my solution. I did not even know it had anything to do with url parameters, the tutorial does not specifically mention “url parameters”, maybe it’s implied but i did not get it, haha :smiley: But when i get the time, i will try again and post my SvelteKit result here :slight_smile:. Thank you for the answer!

The whole application page you are following is somewhat out of date, even in terms of what Vue is doing these days, so we need a review there. So, in that respect, thanks for putting this back on our agenda. :partying_spockle:

1 Like

I got authentication to work! I go to the authentication page like so:

<Button href={getSpeckleAuthPageURL()}> Go to Auth Page </Button>

where the getSpeckleAuthPageURL returns the url:

export function getSpeckleAuthPageURL() {

    // Generate random challenge
    var challenge = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
    // Save challenge in localStorage
    localStorage.setItem(CHALLENGE, challenge)
    // Send user to auth page
    return `${SERVER_URL}/authn/verify/${APP_ID}/${challenge}`
}

After authentication, i get the access code in my root +layout.ts file (i am using SvelteKit):

export const ssr = false

export const load = ({ url }) => {

    const access_code = url.searchParams.get('access_code')

    if (access_code) exchangeAccessCode(access_code)
}

where the exchangeAccessCode is the exact same as in the tutorial:

  // Exchanges the provided access code with a token/refreshToken pair, and saves them to local storage.
export async function exchangeAccessCode(accessCode: string) {
    var res = await fetch(`${SERVER_URL}/auth/token/`, {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            accessCode: accessCode,
            appId: APP_ID,
            appSecret: APP_SECRET,
            challenge: localStorage.getItem(CHALLENGE)
        })
    })

    let data = await res.json()

    if (data.token) {
        // If retrieving the token was successful, remove challenge and set the new token and refresh token
        localStorage.removeItem(CHALLENGE)
        localStorage.setItem(TOKEN, data.token)
        localStorage.setItem(REFRESH_TOKEN, data.refreshToken)
    }
    
    return data
}

Although, now i am wondering, where should i store my APP_SECRET which is used to get auth tokens? I’m building a public app, where the client interacts directly with the Speckle server with no intermediate server. Is it okay to store APP_SECRET within the application? If not, where can i then store it so that it can be used in a “token” request? The tutorial stores it in a .env file not included in the version control, but if APP_SECRET can be found in the request in the application anyway, then what is the big difference?

1 Like