Fork me on GitHub
#clojurescript
<
2016-11-26
>
aengelberg00:11:44

@gfredericks: if something weird were happening, it would be hard to notice unless you had code that depends on the namespace reload order to function properly.

gfredericks00:11:53

Nope I don't do any reloading

seantempesta05:11:53

Has anyone here rolled their own authentication/authorization system with sente? I’m developing an SPA and want to use websockets exclusively for all communication on the server. I think I understand what I need to do, but just wanted to run my logic by someone else to make sure it’s sound.

seantempesta05:11:44

APP INIT: • Check localStorage for previous app state, if found restore • If JWT token is found and expiration date is still valid, initiate sente connection [:handshake [:jwt jwt-token]] • Server authenticates the JWT token and sends back updated data to the client • Client resumes the UI to wherever they left off with the updated state APP LOGIN: • Assuming no local state was found or the JWT token had expired, show login screen • initiate sente connection [:handshake [:login uid device-id bcrypted-password]] • server verifies the bcrypted password matches the db password, saves the JWT token in the database along with the device-id (update-in db [:users :uid :device-id :jwt] jwt-token) and completes the handshake • App stores the JWT token and sends it along in all future sente communication APP LOGOUT: • notify the server to delete the JWT token • delete all localStorage state SERVER: • only store the users bcrypted password and the most recent JWT tokens [:device-id :jwt] • new sente connections: verify the JWT token is valid AND that it matches the database version (during handshake) • existing sente connections: verify the JWT token on every request. Every so often (once an hour?) create a new JWT token extending the expiration date (refreshing the token). Update the db with this new JWT token and send the new token back to the client GOALS: • secure, but not annoying to the user (heavy users only login once per device and their sessions extend indefinitely) • minimize hitting the database on every request (hence JWT) • be able to remotely log users out (via dropping the sente connection and deleting the JWT token from the database)

thheller09:11:43

@seantempesta sounds good, except maybe for the part where I think JWT is nonsense

thheller09:11:08

just let the server generate a unique token on login and send it to the client

thheller09:11:19

which then stores and sends it in place of a JWT

thheller09:11:30

no worries about a JWT impl, same effect

thheller09:11:14

but if you have it running you can probably use it 😉

seantempesta09:11:46

@thheller: Thanks! So you there’s no benefit to using JWT? I just kept running into it when researching best practices.

thheller09:11:46

oh and you didn't mention SSL, which of course is mandatory no matter what

seantempesta09:11:06

everything will be running over SSL

thheller09:11:04

excellent, it is then safe to just [:handshake [:login uid device-id plain-text-password]] as well

thheller09:11:12

and do the bcrypting on the server

thheller09:11:22

well kinda safe 😉

thheller09:11:41

probably best to do it on the client

seantempesta09:11:50

yeah, I wasn’t sure about that. I figured if my server ever got hacked then I could at least prevent the attacker from ever knowing their original password

thheller09:11:16

yeah it is better to do it on the client

thheller09:11:31

just requires the client to have a bcrypt impl 😉

thheller09:11:05

and they all sucked last time I checked

seantempesta09:11:52

ah, I see. I’ll look around.

seantempesta09:11:03

Thanks for the feedback!

thheller09:11:24

curious though: why websocket only?

thheller09:11:45

you need to account for random connection losses

thheller09:11:55

especially for mobile clients

seantempesta09:11:05

I’m doing a datascript <-> datomic sync based app. So I don’t really have API endpoints and really need to push updates to the client.

thheller09:11:32

still websockets can be kind of icky with mobile

bbss09:11:51

server-sent-events yay

seantempesta09:11:58

Is there a problem with websocket reconnects? On reconnection I’m just going to have the client send :database-last-sync-time #inst …, then I’ll push down any changes in bulk and then resume streaming updates.

thheller09:11:33

yeah not a problem, just something to be aware of

thheller09:11:11

also mobile clients will interrupt websockets on sleep

thheller09:11:01

not sure how important mobile is to you

seantempesta09:11:41

can you explain what you mean by interrupt on sleep? Like the client won’t get updates if the app isn’t open?

seantempesta09:11:25

This is a react native project, so yes mobile is very important to me. 🙂

thheller09:11:22

hmm no idea about react native

thheller09:11:04

mobile browsers close websockets when selecting a different tab or when locked

thheller09:11:13

they really don't like open network connections since they need to keep the radio on

thheller09:11:18

which drains battery

thheller09:11:21

which sucks

thheller09:11:32

so they kill connections asap

thheller09:11:44

but again .. no idea how react native handles this

seantempesta09:11:00

yeah, I’ll have to look into this

thheller09:11:02

but in general you want mobile clients to idle as much as possible

thheller09:11:02

saving battery matters 🙂

seantempesta09:11:37

very true. I don’t really care about background updates, but I wanted the UI to be realtime whenever it’s open. I figured websockets were the best solution, but maybe I should look into push notifications instead.

thheller09:11:28

well you really only need to update the UI when the user is using it

thheller09:11:49

so if you implement a re-connect logic like you suggested you should be fine

thheller09:11:17

just something I wasn't aware of when testing websockets on mobile

thheller09:11:22

they disconnect a lot 😛

seantempesta09:11:03

good to keep in mind!

thedavidmeister10:11:53

i thought sente automatically attempts to reconnect?

Aron14:11:53

anyone tried d3 + canvas?

Aron14:11:45

i want to learn clojurescript and I think this would be a good example to reimplement at first http://bl.ocks.org/ashnur/raw/910a4fdc3556a32f435f248c04108c8f/

Geoffrey Gaillard14:11:51

Hi everybody ! I'm facing a situation I don't understand. I'm compiling a clojurescript project in dev, pre-min, and min modes, these mode are repsectively optimised with :none, :whitespace, and :advanced, nothing extraordinary… It compiles well in all cases, but when I run the minificated one (`:advanced`) I get this error in my browser:

Importing test-only code into non-debug environment: goog.testing.PseudoRandom(…)
It doesn't happen with the :whitespace one. Well, this message is clear and I understand it well. But I can't find which file/dependency is causing it. I think there is something about the closure compiler I don't know, and neither the stacktrace Google is not helping me at all right now … Do one of you ever encountered this behaviour ?

thheller14:11:57

@ggaillard something must be doing (:require [goog.testing.PseudoRandom])

thheller14:11:43

or otherwise require a testing namespace

thheller14:11:43

the warning is only emitted when js/goog.DEBUG is false

thheller14:11:00

no idea if other build tools offer this API

thheller14:11:59

just run it in a REPL, it will tell you which namespace is using the goog.testing.PseudoRandom

mikebelanger15:11:00

Has anyone here done any beat detection stuff with Clojurescript? I'm just looking at the different javascript libraries out there, but I'd like to hear your thoughts

mikebelanger15:11:12

sorry maybe I should've posted this to clojure-art 😛

raynes18:11:58

I detect beats with my ear and central nervous system

Aron23:11:30

can't find one example of clojurescript + d3 + canvas

Aron23:11:21

and nvim-parinfer touches the file, so i always have to save before i switch buffers, and it's really annoying