Yeah, if you want to basically tie the app to a specific piece of hardware, it’s a little more complicated.
I can see that, if your use case is like some sort of dashboard for the marketing department of some organization, you can’t allow open web access. There are all sorts of commercial solutions of varying costs for managing access to apps from specific hardware devices and that may be one route.
Kind of a hinky solution that I could see working most of the time would be to temporarily enable the creation of a user or users via an oauth like log in with Google. You create the kiosk user this way. (e.g., someone in the organization creates a Google account that will represent the kiosk user and then you or them [someone who knows that user’s Google credentials] “signs up with Google” as that user.
Now you have a User in the database representing kiosk user. Now you as the admin of the app can actually run the app as that user. (From the data tab.) Note that you don’t even have to know their Google credentials – using “run as” will authenticate you to your app as that user.
You have a couple of options at this point:
You could in your database just give them some boolean flag like “Kiosk User” and set it to yes. And then you could use this to understand that the logged in entity is the Kiosk and not someone else. (And you set up privacy rules using that.)
Rather than a boolean flag, I prefer something a little more complex (and possibly more secure as it keeps you from making boneheaded errors that might expose the existence of the Kiosk User flag in the browser). What you do is run an action as this Kiosk User that creates a new object in the database. (There’s a page you create temporarily and then destroy with a button on it, when clicked, it creates the object.) You can call this object it whatever you like and it needs no fields on it. Let’s call it a “KioskUser” or something. It looks like this:
You now have a KioskUser object in your database (just one of them) and it is created by the Kiosk User represented by that Google account. Destroy the means to create a KioskUser. Now nobody can create a KioskUser (except for you in your backend, and even if you do, you can’t create the right kind of KioskUser as, without “run as…” any KioskUser you create will be created by the system - null user).
Now you set up a privacy rule for KioskUser: A KioskUser is only visible to its creator:
Now here’s the cool part – and yes, I’ve explained all of this before as a way of creating a secure Administrator role - a search for KioskUsers will always come up empty UNLESS the authenticated user has created a KioskUser.
You can now do stuff like “When Do a search for KioskUsers:first item is empty… redirect to some stupid page… do not show the page… etc.” And no field of the KioskUser object is visible, not even to its creator. All we can know about it is that it exists.
And, even if someone manages to log in/sign up and create some other User, they can never create a KioskUser nor can they learn anything about it. Etc. Etc.
NOW, how might we handle logging in without a keyboard? (You might see where all this is going.) What we’d do is that one time you actually need a keyboard attached to the kiosk device. And you need it to log into the app once as that Google account we created earlier. What we’re gonna do use Chrome as our browser (why would you use anything else, anyway?) and on that first login we use Chrome’s integration with Google to save the kiosk user login credentials in the browser.
The device itself would have a shortcut on the desktop or whatever that launches Chrome pointing to our app’s URL. We can then have our start page have a log in button that does log in with Google. The credentials being saved in this browser, we’ll be able to touch select that saved user and log in…
We’ll be able to start the kiosk every day without a keyboard as long as some dipshit doesn’t clear the saved passwords and stuff.
Something to keep in mind: Someone could still hit the login page and authenticate as any Google user and doing so will automagically create a User. However, after that step, we can just have a delete user step that triggers if “Do a Search for KioskUsers:first item is empty”. Ha ha! Take that, unauthorized user!!!
(Now you can see that probably you as the admin should also create a KioskUser object or testing your project is going to be impossible, but I think this is obvious.)
Even if we don’t immediately nuke invalid User objects, it kind of doesn’t matter as you’ll have designed your app such that only the kiosk user account can see anything or do anything useful. But why let those useless Users stay in our database, right?
Again, all of the above is only if your app is going to deliver some sort of info that should only be available via authentication.
If your Kiosk is not for some private application, but is instead a point-of-presence device with info – like a directory for a mall or museum or something – I’d argue for designing it to work for no User at all (works fine for not-logged-in Users).
And the reason for that is EVERYONE is walking around with a web browser and we do not need to be in front of a physical kiosk at all. In fact, the Kiosk start page (all the pages, really) should have a little note on them:
“Take me with you: https:// some friendly URL”
Or, if you wanna be all old-fashioned, put up one of those dumb QR codes that nobody ever uses, but that marketers love.