I am using Clojure / Friend, and I would like to hijack a session from a neighbouring node.js server :)
What I mean is that there is a node.js + Express 3 server that stores sessions into a redis database, using connect-redis. I have access to the node.js source code, and therefore to the secret passed to the express session used to generate the sid. I modified the connection section to look like this (the built-in in-memory store was used previously) :
var session = require('express-session')
, RedisStore = require('connect-redis')(session)
, redis = require('redis')
, client = redis.createClient();
...
app.use(session({
secret: "super-secret-key",
store: new RedisStore({client : client,
ttl : 60*60*24,
prefix : 'sess:'})
}));
I can see the sessions stored in Redis :
// using redis-cli
KEYS *
1) "sess:yNV3MQOOTZSEgzl0RH2lyWVW"
The login page is situated on the node.js side of the app. But the routes of the API are shared (via nginx) between Node.js and Clojure, so I receive the cookies in the incoming requests in my Compojure / Friend app.
I am struggling to get the Friend custom-credential function right :
(defn custom-credential [{:keys [username password] :as trial}]
(let [cookie (...)
redis-session (...)
is-signature-valid (...)]
;; I can get all the above bindings just fine
;; ie. I extract the cookie from the request
;; I read the cookie ID and fetch the cookie content from Redis
;; I extract the signature of the cookie and check it (I replicated [node-cookie-signature][8])
(when is-signature-valid
{:identity "cookie-id"})))
(defn secured-routes [unsecured-routes]
(friend/authenticate
unsecured-routes
{:allow-anon? true
:credential-fn custom-credential
:workflows [(workflows/http-basic)]}))
I have several problems :
I am redirected to the login page even when my authentication function returns an
{:identity ..}mapBut I cannot figure out how to plug it into Friend so that the cookies work as well. Using the default
memory-storethen the cookie is replaced by a default ring-cookie (obviously not what I want). I tried writing a custom cookie-store using Redis as a backend, but I need to write JSON to keep the node compatibility, and I loose the::userinformation.
Note : I am quite flexible at this point so if I should use something else than Friend or Compojure I would also accept that.
Sorry for the long post, I really hope someone can help.