This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-29
Channels
- # beginners (1)
- # cider (7)
- # cljsrn (6)
- # clojars (3)
- # clojure (35)
- # clojure-nl (2)
- # clojure-spec (5)
- # clojure-uk (9)
- # clojurescript (18)
- # clojurex (1)
- # community-development (2)
- # cursive (27)
- # datomic (12)
- # duct (11)
- # emacs (5)
- # hoplon (5)
- # immutant (2)
- # leiningen (1)
- # luminus (15)
- # nyc (1)
- # om (9)
- # om-next (5)
- # onyx (55)
- # parinfer (1)
- # re-frame (3)
- # reagent (44)
- # reitit (11)
- # ring-swagger (4)
- # shadow-cljs (25)
- # videos (1)
I’m having trouble grokking REACT API authentication as explained here: http://www.luminusweb.net/docs/services.html. The Authentication section is cursory and involves 2 “restructure-params” defmethods without a corresponding defmulti. This kind of high magic without basic explanation just feeds the commonly-held view that Clojure is for experts.
Is there a simpler explanation of how this works? It seems I can’t avoid using this code if I need to implement a REST API in Luminus.
Hi @clojer, just quickly, if you’re coming from say Java/Ruby/etc worlds, like id did. Yes it can be a bit different and not immediately obvious, especially given that in clojureworld, there’s more focus on libraries v frameworks, so luminus is a approach that wires some ‘curated’ set of libraries up for you. For your specific question, what’s happening there is a combination of ring middleware that actually handles the authentication, that could be pulling the id off of a JWT, or per the example, pulling it from the session,etc. Then, in order to use features of the api library (compojure-api), like providing the current user , issuing an unauthorized, etc) the restructure-param calls defining a mapping from the middleware (defined in middleware.clj in a generated project) to the api. Such that say current-user is resolved correctly. To fully understand this, you’ll need to peruse the ring and compojure-api docs. But if you’ve used the appropriate luminus options when you create your project, it should pretty much work out of the box, or with slight modifications, depending on your requirements. For instance, for some of my projects I use the Auth0 third-party authentication service, I’ve alternatively written my own, and used third-party middleware to properly decode its tokens, and made the appropriate changes to my restructure-param calls.
I don’t see any code here which explains how to hook this all up with a database connection which verifies the username and password. So much seems to be assumed.
ok by default a database enabled luminus project is going to expose a conn
component
This is anything but simple which is what I thought Clojure was all about. “Injection” doesn’t sound very idiomatic.
well, this would be more a discussion of the general software architecture, than clojure specifically. Yes you can and should do pure functions, etc to the extent possible, but you need side-effects for ‘interesting’ stuff like writing to a database. And there’s unavoidable ‘global state’ you need like database connections. libraries like mount, which luminus uses provide a way to get at those kinds of things. You should still in say your ‘user managment’ namespace make things as pure as possible, like separate code that reads/writes to the database from code that makes business decisions about users. But in this case just to get started, you just need say a couple functions, perhaps like
(ns myapp.users ..)
(defn save-user [username password conn] ...)
(defn get-user [username conn] ...)
; a 'pure' checker
(defn password-valid? [password db-password] ... do bcrypt, etc check here)
Also, a good practice is to always pass your functions what they need, so even say the side-effecting save-user above, should have it’s connection passed in where you’re calling it, as opposed to referencing directly in the namespace