Frontity basic authentication using login and password

Hey guys,

I didn’t find any resources how to implement basic authentication using frontity.
I’d like to extend server functionality and use something like koa-basic-auth. According to my quick research it’s not possible yet.

I decided to use beforeSSR function to solve that:

beforeSSR: ({ state, libraries }) => async ({ ctx }) => {

        const { header } = ctx.request;

        const credsFit = (authHeader) => {
          const parts = authHeader.split(' ')[1].split(';')
          const [login, lVal] = parts[0].split('=');
          const [pw, pVal] = parts[1].split('=');

          if (login === 'login' && lVal === 'admin' && pw === 'password' && pVal === 'p4$$w0rd') {
            return true;
          } else {
            return false;
          }
        }

        if (!header.authorization) {
          return;
        }

        if (header.authorization && credsFit(header.authorization)) {
          return ctx.res.send({ authorized: true });
        } else {
          return ctx.res.send({ authorized: false });
        }
      }

and my protector HOC with function :

const handleSubmit = async (e) => {
    e.preventDefault();

    const { login, pw } = creds;

    if (login?.length && pw?.length) {

      try {
        const res = await fetch('/', {
          headers: {
            'Authorization': `Basic login=${login};password=${pw}`
          }
        })

        const data = await res.json();

        if (data.authorized) {
          setAuthorized(true);
        } else {
          alert('wrong login and/or password')
          setAuthorized(false);
        }
      } catch (err) {
        console.log(err);
      }

    } else {
      alert('set login and password');

    }
  }

this ad-hoc solution works well if I start frontity using frontity dev but as soon as I build project and start serving using frontity serve --port $PORT I can’t access node res object in ctx and use it’s send or json method.

I am getting: TypeError: e.res.send is not a function.

1. Can you help me how to secure whole site using simple login and password - its not ready yet and I want to give access only to my client - for review purposes.
2. What’s wrong with my solution? Why is it working in dev and not if its built & served.

Hey @novakjano33 ! :wave:

I think that you problem is that Koa does not support handling the node Response directly using ctx.res.send() API. You might be able to access the native node response and request objects by setting ctx.respond = false, but it’s not recommended.

So I wonder why does this seem to work fine in dev I think that it should not work in either… :thinking:

However, with your current approach you do not actually need to add any code in the beforeSSR because the “authorization” is done entirely on the client side using the setAuthorized() function. I deduce that setAuthorized() is setting a boolean in react state or in Frontity state which could then be accessed by anybody with Chrome DevTools. So, if you’re not worried about that I would just hardcode a check directly in a top-level react component without making any request to the backend. Again, this approach is not “secure” at all but perhaps you only need a little bit of obscurity and not a complete solution.

If this is not sufficient then unfortunately there is not a good way to add basic authentication to Frontity at the moment until we merge Server Extensibility into the framework.

thank you for your reply! Correct I didn’t needed complete solution so I did it as you mentioned - top level component checking authorized state. Hopefully server extensibility will come soon, lookin forward to have it asap.