DEV Community

Fabian Diez
Fabian Diez

Posted on

Using BaaS with custom Backend

Let me preface this by saying that I have little experience with Authentication on the front-end side, as my professional work is mostly backend/cloud or has authentication already set up so I rarely have to deal with setting up an authentication flow from front- to backend myself.
However, I wanted to expand my knowledge on this, and looked up a few modern solutions for authentication solutions in the frontend - this is where I am a bit confused and could use some guidance.
From my research, it looks like a lot of project are using BaaS like Firebase or Supabase, which looks very promising for the type of side-project I am planning to do. Unfortunately it looks like the platform are (more or less) strictly BaaS, where you would write you backend logic using either SSR or with serverless functions on each respective platform. I understand the appeal of this - and I thinks it's quite a clean approach - but it not something I would like to do for my current project, as I have quite a perfectly working API written in Rust which I'd like to use as part of this project.

So my question would be:

What would be a clean, modern approach for perform frontend authentication? I am using Svelte for my frontend, and I've taken a look at NextAuth.js. But as this is still im Beta, there must be some better options available as well, right?

Is it possible to use a platform like Supabase to only perform Authentication, i.e. provide the frontend which credentials, which can then be used in my own, custom backend? Or are people usually only using these service as part of a "full-stack" application with SSR - in contrast to a more traditional approach with a custom backend.

Any tips/help would be appreciated, thanks!

Latest comments (4)

Collapse
 
fabiandiez profile image
Fabian Diez

Thanks for all the comments, after doing a bit more research I settled on using auth0 as an Authentication provider - they provide a generic spa-sdk that was decently easy to integrate into my Svelte app.

Collapse
 
sroehrl profile image
neoan

I am a little confused. If you want to use your custom API, then you have to secure it directly. I am not sure how you built it, but with rust I assume you utilized something like rocket? If so, have a look at their middleware (they call it forwarding guards).
Either way, not securing the actual API makes any form of authentication pointless.

Next, you say you are using svelte, but then point to a react based auth solution. This obviously won't work for you.

Generally, I would recommend JWT tokens instead of cookies/sessions. I personally never used any frontend libraries to achieve this. Use your framework's store or your browser's storage possibilities to store the token and send it as authentication header on each request.

On the backend, use a JWT crate to send a valid JWT after successful authentification and guard your routes with it.

Collapse
 
fabiandiez profile image
Fabian Diez

Thanks for your quick response, I would indeed prefer to implement a JWT based authentication for my backend API. I only pointed to NextAuth, as it recently announced support for Svelte, and seems to be a framework a lot of people point to when it comes to handling Auth. But as I said - I am quite unaware of frontend tooling in regards to this. Would you suggest any other frameworks/libraries for handling Authentication in Svelte?

Collapse
 
sroehrl profile image
neoan • Edited

Don't overcomplicate it. You don't need any library in your frontend to handle auth.
You handler could look like this:


// you might consider doing this differently
let token = sessionStorage.token 

const getOptions = (method, payload = null) => {
    const obj = {
        method: method.toUpperCase(),
        headers: {
            'Authorization': 'bearer ' + token,
            'Content-Type': 'application/json'
        }
    }

    if(payload){
        obj.body = JSON.stringify(payload)
    }
    return obj;
}

export const apiCall = async (method, url, postData) => {
    const call = await fetch(PUBLIC_API_PATH + url, getOptions(method, postData))
    if(call.status >= 200 && call.status <= 299){
        return await call.json();
    }
   throw Error(call.statusText)
}

// and maybe for convenience:
export const post = async (url, postData = {}) => apiCall ('post', url, postData)
export const get = async (url) => apiCall ('get', url)
...
Enter fullscreen mode Exit fullscreen mode