使用passport.js和express.js(node.js)创建一个安全的oauth API [英] Make a secure oauth API with passport.js and express.js (node.js)

查看:156
本文介绍了使用passport.js和express.js(node.js)创建一个安全的oauth API的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具体的问题,除非我没有以正确的方式做事情。



我有两个方面的应用程序,一个客户端(html站点)和一个API(用express + mongodb构建)。 API将需要安全访问。他们都在不同的领域,现在让我们的网站在domain.com上,我的API在api.com:3000。



我已经添加了护照获取Github的访问令牌,因为我正在使用他们的数据创建用户,所以我可以使用Github登录。



我目前的流程是:



1)客户端(网站)在API上打开弹出窗口

  window.open(http://api.com:3000/oauth)

2)快递服务器启动护照流程:

  app.get('/ oauth',passport.authenticate github'),function(req,res){

});

对于策略,我使用了此代码



3)我重定向回调到一个关闭弹出窗口的URL(使用window.close()的javascript):

  app.get('/ oauth / callback',passport.authenticate('github',{failureRedirect:'/'}),function(req,res){
res.redirect('/ auth_close');
});

在这一点上,一切都很好,我现在登录了API。我的问题是如何获取数据回到客户端,因为客户端还不了解accessToken,用户或用户ID。



所以,从客户端打开弹出窗口的网站),我尝试了不同的方法:




  • 从弹出窗口获取值不起作用的重定向,我没有跟踪弹出的javascript信息


  • 调用我的API来获取会话中的当前用户,例如 http://api.com:3000/current
    一个请求,不理想,但这一个工作。但是,我仍然有一个问题。




如果我从浏览器,因为浏览器在头部请求中发送快速会话cookie:

  Cookie:connect.sid = s%3AmDrM5MRA34UuNZqiL%2BV7TMv6。 paw6O%2BtnxQRo0vYNKrher026CIAnNsHn4OJdptb8KqE 

问题是我需要从jquery或类似的请求,这就是它失败,因为会话没有发送。所以用户没有返回:

  app.get('/ current',function(){
//问题在这里,req.user由于会话而不确定与ajax调用!
});

我找到了一种方法,使其工作,但我不高兴,因为我会交叉-browsers CORS问题,它正在添加来表达:

  res.header(Access-Control-Allow-Credentials,真正); 

然后在jquery ajax调用中添加withCredentials字段,如这里



要设置的fieldName-fieldValue对的映射本机XHR对象。例如,如果需要,可以使用它将跨域请求的Credentials设置为true。

  $。ajax({
url:a_cross_domain_url,
xhrFields:{
withCredentials:true
}
});

我也不满意,因为我丢失了我的标题上的通配符: Access-Control-Allow-Origin ,我需要指定一个域,如 here



所以,我不知道该做法我应该在这里,唯一需要的是客户端从护照oauth进程获取accessToken或userID。这个想法是在API的每次调用中使用该标记来验证调用。



任何线索?

解决方案

我有同样的问题。我在登录页面上使用本地策略,然后检查用户是否在其他请求的会话中。



正如您所说,解决方案是使用CORS为了使用XMLHTTPRequest将会话ID传递到一个cookie中。



我不想使用在所有浏览器上还没有工作的CORS,而是使用CORS访问其他请求的令牌。我使用的工作流程如下:

  POST / login 




  • 身份中传递用户名和密码。

  • 使用本地策略进行身份验证。

  • 响应返回用户对象,包括access_token



GET / endpoint / abc123?access_token = abcdefg




  • 从登录响应获取的令牌

  • 使用承载策略进行身份验证(在护照http-bearer中)



Express中现在不需要会话。



我希望这个替代方法有助于。


I've got I think a specific problem, unless I'm not doing things in the right way.

I've got an application with 2 sides, a client (html site), and an API (built with express + mongodb). The API will need to be securely accessed. They both are on different domains, for now let's say my site is on domain.com and my API is on api.com:3000.

I've added passport to get an access token from Github as I'm creating my users with their data, so I can have a "Sign in with Github" basically.

My current process is:

1) the client (the site), opens a popup on the API

window.open("http://api.com:3000/oauth")

2) The express server, start the passport process:

app.get('/oauth', passport.authenticate('github'), function(req, res) {

});

For the strategy, I used this code.

3) I redirect the callback to a url that closes the popup (javascript with a window.close()):

app.get('/oauth/callback', passport.authenticate('github', { failureRedirect: '/' }), function(req, res) {
    res.redirect('/auth_close');
});

At that point, all is fine, I am now logged in the API. My problem is how to get data back to the client, as the client doesn't know anything yet about accessToken, user or user id.

So, from the client (the site that opens the popup), I tried different approaches:

  • getting a value from the popup: doesn't work because of the redirection, I lose track of the popup javascript information

  • calling my API to get the "current user" in session, such as http://api.com:3000/current One more request, not ideal, but this one work. However, I still have a problem.

This /current url is returning the user if I reach it from the browser, because the browser send in the header request the express session cookie:

Cookie:connect.sid=s%3AmDrM5MRA34UuNZqiL%2BV7TMv6.Paw6O%2BtnxQRo0vYNKrher026CIAnNsHn4OJdptb8KqE

The problem is that I need to make this request from jquery or similar, and that's where it fails because the session is not sent. So the user is not returned:

app.get('/current', function() {
    // PROBLEM HERE, req.user is undefined with ajax calls because of the session!
});

I found a way of making it work but I'm not happy with because I'll have cross-browsers CORS problems, it is adding to express:

res.header("Access-Control-Allow-Credentials", "true");

And add the withCredentials field in a jquery ajax call, as explained here.

A map of fieldName-fieldValue pairs to set on the native XHR object. For example, you can use it to set withCredentials to true for cross-domain requests if needed.

$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

I am also not happy with this as I'm losing the wildcard on my header: Access-Control-Allow-Origin, I need to specify a domain, as explained here.

So, I'm not sure the approach I should take here, the only thing I need is the client getting either an accessToken, or a userID back from the passport oauth process. The idea is using that token in each call to the API to validate the calls.

Any clue?

解决方案

I had the same issue. I was using the Local Strategy on the login page, and then checking to see if the user was on the session on other requests.

As you say, the solution is to use CORS in order for the session ID to be passed in a cookie using XMLHTTPRequest.

Instead of using the CORS which does not yet work on all browswers, I deceided to use access tokens on other requests. The workflow I used is as follows:

POST /login

  • Username and password get passed in the body.
  • Authentication using Local Strategy.
  • Response returns the user object, including the access_token

GET /endpoint/abc123?access_token=abcdefg

  • Token obtained from the login response
  • Authentication using Bearer Strategy (in passport-http-bearer)

Sessions are now not needed in Express.

I hope this alternative helps.

这篇关于使用passport.js和express.js(node.js)创建一个安全的oauth API的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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