使用passport.js和express.js(node.js)创build安全的oauth API
我想我有一个特定的问题,除非我没有以正确的方式做事。
我有一个双方的应用程序,一个客户端(html网站),和一个API(使用express + mongodb构build)。 该API将需要安全访问。 他们都在不同的领域,现在让我们说我的网站是在domain.com上,我的API是在api.com:3000。
我已经添加了护照从Github获取访问令牌,因为我使用他们的数据创build了我的用户,所以我可以基本上有一个“用Githublogin”。
我目前的过程是:
1)客户端(站点),在API上打开一个popup窗口
window.open("http://api.com:3000/oauth")
2)快递服务器,启动护照stream程:
app.get('/oauth', passport.authenticate('github'), function(req, res) { });
对于这个策略,我使用了这个代码 。
3)我将callbackredirect到一个url,closurespopup窗口(JavaScript与window.close()):
app.get('/oauth/callback', passport.authenticate('github', { failureRedirect: '/' }), function(req, res) { res.redirect('/auth_close'); });
在这一点上,一切都很好,我现在login在API中。 我的问题是如何将数据返回给客户端,因为客户端还不了解accessToken,用户或用户ID。
所以,从客户端(打开popup窗口的网站),我尝试了不同的方法:
-
从popup窗口中获取值:由于redirect而不工作,我失去了popup式JavaScript信息的轨道
-
调用我的API来获取会话中的“当前用户”,如http://api.com:3000/current另外一个请求,并不理想,但是这个工作。 但是,我仍然有一个问题。
如果我从浏览器到达它,这个/当前url正在返回用户,因为浏览器在头部请求中发送快速会话cookie:
Cookie:connect.sid=s%3AmDrM5MRA34UuNZqiL%2BV7TMv6.Paw6O%2BtnxQRo0vYNKrher026CIAnNsHn4OJdptb8KqE
问题是我需要从jquery或类似的请求,这是失败的地方,因为会议不发送。 所以用户不会被返回:
app.get('/current', function() { // PROBLEM HERE, req.user is undefined with ajax calls because of the session! });
我find了一种方法使其工作,但我不满意,因为我将有跨浏览器的CORS问题,它是增加expression:
res.header("Access-Control-Allow-Credentials", "true");
并在jquery ajax调用中添加withCredentials字段,如此处所述。
要在本地XHR对象上设置的fieldName-fieldValue对的映射。 例如,如果需要,可以使用它将withCredentials设置为true来处理跨域请求。
$.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } });
我也不满意,因为我失去了我的头上的通配符: Access-Control-Allow-Origin
,我需要指定一个域,如此处所述。
所以,我不确定我应该采取的方法,唯一需要的是客户端从护照oauth进程获取accessToken或userID。 这个想法是在API的每个调用中使用该标记来validation调用。
任何线索?
我遇到过同样的问题。 我在login页面上使用本地策略,然后检查用户是否在其他请求的会话。
正如你所说,解决scheme是使用CORS,以便使用XMLHTTPRequest在cookie中传递会话ID。
我没有使用在所有browswers上还没有工作的CORS,而是在其他请求上使用访问令牌。 我使用的工作stream程如下:
POST /login
- 用户名和密码传入正文。
- 使用本地策略的authentication。
- 响应返回用户对象,包括access_token
GET / endpoint / abc123?access_token = abcdefg
- 令牌从login响应中获得
- 使用承载策略进行身份validation(在护照 – http-bearer中)
Express中现在不需要会话。
我希望这个替代有帮助。
在快速应用程序中configuration任何内容之前,请使用以下内容(完全相同)设置跨域响应的标题:
app.use(function(req, res, next) { res.header('Access-Control-Allow-Credentials', true); res.header('Access-Control-Allow-Origin', req.headers.origin); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'); if ('OPTIONS' == req.method) { res.send(200); } else { next(); } });
- 如何使用Advanced REST Client或PostmantestingExpress / node REST API后端?
- 如何提取nodejs上的数组
- 有没有办法获得Firebase身份validation用户的UID?
- 我应该如何构build我的数据库和API服务器为基于回合的多人iPhone的棋盘游戏? (考虑nodejs,mongo,沙发等)
- 有没有办法使用Unsplash API获取与照片相关的所有标签?
- 在AngularJS和数据库之间保持唯一标识符同步的最佳方法是什么?
- 使用Node JS代理http并修改响应
- 具有工作队列devise模式的API
- 用于Express.js的Rest APIvalidation和会话pipe理