在Node.js和Clojure之间共享用户会话 [英] share user sessions between Node.js and Clojure

查看:129
本文介绍了在Node.js和Clojure之间共享用户会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Clojure / 朋友,我想从相邻的node.js服务器劫持会话)



我的意思是有 node.js + Express 3 服务器,将会话存储到 redis 数据库中,使用 connect-redis
我可以访问node.js的源代码,因此将秘密传递给用于生成sid的express会话。我修改了连接部分,看起来像这样(内置的内存存储是以前使用过的):

  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:'})
}));

我可以看到存储在Redis中的会话:




//使用redis-cli
KEYS *
1)sess:yNV3MQOOTZSEgzl0RH2lyWVW



登录页面位于应用程序的node.js侧。但是API的路由在Node.js和Clojure之间是共享的(通过nginx),所以我在Compojure / Friend应用程序中接收到传入请求中的cookie。



我正在努力获得朋友的自定义凭证函数正确:

 (defn custom-credential [{:keys [username password] :as trial}] 

(let [cookie(...)
redis-session(...)
is-signature-valid(...)]
;;我可以得到所有上面的绑定只是罚款
;; ie。我从请求中提取cookie
;;我读取cookie ID并从Redis获取cookie内容
;;我提取cookie的签名并检查它(我复制[node-cookie-signature] [8])

(当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)]}))
$ p>

我有几个问题:




  • 我重定向到登录页面,即使我的身份验证函数返回 {:identity ..} 地图


  • 如何将它插入到朋友,使cookie也工作。使用默认的内存存储然后cookie被一个默认ring-cookie替换(显然不是我想要的)。我尝试使用Redis作为后端编写一个自定义Cookie存储,但是我需要编写JSON以保持节点兼容性,而且我放松了 :: user 信息。 p>




注意:我现在很灵活,所以如果我应该使用 / code>或 Compojure 我也接受。



对不起,希望有人能帮助。

解决方案


如何获取我的验证功能的Cookie内容?


响铃请求将包含客户端发送的任何Cookie,但是如果您的Clojure服务器位于不同的域中,则可能不会发送这些Cookie。


如何根据Cookie的内容验证用户?也就是说。如何确保cookie没有被改变(即复制connect-redis正在做的秘密)?


最佳做法是将cookie作为随机数,并在redis中存储会话详细信息。如果这是节点服务器的工作原理,那么你可以在Redis中查找详细信息。或者,如果客户端提供了加密的会话cookie,那么您将需要以与Node相同的方式对其进行解密。



或者,您可能需要查看JWT身份验证令牌,这些令牌设计为由许多不同的服务器共享和验证。


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 ..} map

  • But I cannot figure out how to plug it into Friend so that the cookies work as well. Using the default memory-store then 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 ::user information.

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.

解决方案

How do I get the cookie contents on my validating function ?

The ring request will contain any cookies that the client sent, however it may not send those cookies if your Clojure server is on a different domain.

how do I validate the user from the content of the cookie ? Ie. how can I make sure the cookie has not been altered (ie. replicate what the connect-redis is doing with the secret) ?

Best practice is for the cookie to be a random number, and to store session details in redis. If that's how your Node server works then you can just lookup the details in Redis. Alternatively if the client provided an encrypted session cookie, then you will need to decrypt it in the same manner as Node does.

Alternatively, you might want to look at JWT auth tokens, which are designed to be shared and authenticated by many different servers.

这篇关于在Node.js和Clojure之间共享用户会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆