使用Passport和OAuth2 +社交网络的NodeJS REST身份验证 [英] NodeJS REST authentication using Passport and OAuth2 + social network
问题描述
我正在使用 NodeJS
开发 REST
api。为了进行身份验证,我决定使用 Passport
。我想要真正的RESTful API。因此,这意味着我必须使用令牌而不是会话。
I'm working on REST
api using NodeJS
. For authentication I decided to use Passport
. I want truly RESTful api. So it means I have to use tokens instead of sessions.
我想让用户使用用户名和密码或使用Facebook,Google和Twitter等社交网络登录。
I want to let users login using username and password, or using social networks like Facebook, Google and Twitter.
我制作了自己的 OAuth2.0
服务器来发布 Access
和使用
。因此,现在我可以注册新用户,然后向其颁发令牌。 oauth2orize
模块刷新令牌
我遵循了本教程:
I make my own OAuth2.0
server for issuing Access
and Refresh tokens
using oauth2orize
module. So now I can register new user and then issue them tokens.
I followed this tutorial:
http://aleksandrov.ws/2013/09/12/restful-api-with-nodejs-plus-mongodb/
验证用户的路线:
// api ------------------------------------------------------------------------------------
app.get('/api/userInfo',
passport.authenticate('bearer', { session: false }),
function(req, res) {
// req.authInfo is set using the `info` argument supplied by
// `BearerStrategy`. It is typically used to indicate scope of the token,
// and used in access control checks. For illustrative purposes, this
// example simply returns the scope in the response.
res.json({ user_id: req.user.userId, name: req.user.username, scope: req.authInfo.scope })
}
);
所有这些都很好。不幸的是,我不知道如何实现社交身份验证。
All this works quite well. Unfortunately I don't know how to implement social authentication.
我正在阅读本教程:
http://scotch.io/tutorials/javascript/easy-node-authentication-facebook
但是在本教程中,它们并不是真正的RESTful API。我已经按照本教程实现了用户架构,其中本地用户的令牌存储在单独的模型中。
But in this tutorial they are not making a truly RESTful api. I already implemented user schema according this tutorial where tokens for local user are stored in separated models.
// define the schema for our user model
var userSchema = mongoose.Schema({
local: {
username: {
type: String,
unique: true,
required: true
},
hashedPassword: {
type: String,
required: true
},
created: {
type: Date,
default: Date.now
}
},
facebook: {
id: String,
token: String,
email: String,
name: String
},
twitter: {
id: String,
token: String,
displayName: String,
username: String
},
google: {
id: String,
token: String,
email: String,
name: String
}
});
但是现在,我如何验证用户?
But now, how can I verify user?
passport.authenticate('bearer', { session: false }),
这仅针对我的数据库验证载体令牌,但是我如何验证社交令牌?我想念什么吗?
this is verifying only bearer token against to my db, but how can I verify social tokens? Am I missing something?
推荐答案
我正在将Facebook登录用于我自己的RESTful API,用于我的记事本应用。我以将其用作网页的形式启动了该应用程序,但登录后仍然可以通过API进行通信。
I am using Facebook login for my own RESTful API for my Notepads app here. I started the application as one that will be used as a web page but still the communication after the login will be through the API.
然后我决定创建一个将使用该API的同一应用的移动版本。我决定采用这种方式:移动应用通过Facebook登录,并将Facebook用户ID和FB访问令牌发送到API,API调用Facebook的API来验证这些参数,以及是否成功注册了新用户(或登录到我的应用的数据库中的现有令牌),为此用户创建一个自定义令牌,并将其返回给移动应用。
Then I decided to create a mobile version of the same app that will use the API. I decided to make it that way: The mobile app logs in through Facebook and sends the facebook user id and FB access token to the API, the API calls Facebooks's API to verify these params and if successful registers a new user(or logs in an existing one) in my app's DB, creates a custom token for this user and returns it to the mobile app. From here the mobile app sends this custom token to authenticate the app with the API.
这里是一些代码:
API中的身份验证(使用fbgraph npm模块):
The auth in the API (uses the fbgraph npm module):
var graph = require('fbgraph'),
Promise = require('bluebird')
...
Promise.promisify(graph.get);
...
var postAuthHandler = function (req, res) {
var fbUserId = req.body.fbId,
fbAccessToken = req.body.fbAccessToken,
accessToken = req.body.accessToken;
...
graph.setAppSecret(config.facebook.app.secret);
graph.setAccessToken(fbAccessToken);
var graphUser;
var p = graph.getAsync('me?fields=id,name,picture')
.then(function (fbGraphUser) {
//when the given fb id and token mismatch:
if (!fbGraphUser || fbGraphUser.id !== fbUserId) {
console.error("Invalid user from fbAccessToken!");
res.status(HttpStatus.FORBIDDEN).json({});
return p.cancel();
}
graphUser = fbGraphUser;
return User.fb(fbUserId);
})
.then(function (user) {
if (user) {
//user found by his FB access token
res.status(HttpStatus.OK).json({accessToken: user.accessToken});
//stop the promises chain here
return p.cancel();
}
...create the user, generate a custom token and return it as above...
用户模型:
var userSchema = new mongoose.Schema({
facebookId: { type: String, required: true, unique: true },
accessToken: { type: String, required: true, unique: true },
name: { type: String, required: true },
photo: { type: String, required: true },
categories: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Category' }],
notepads: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Notepad' }]
});
移动应用程序中的Facebook身份验证:
The Facebook auth in the mobile app:
auth: function(fbId, fbAccessToken) {
return $http({
url: apiBase + '/users/auth',
data: {
fbId: fbId,
fbAccessToken: fbAccessToken
},
method: 'POST',
cache: false
});
},
...
https://github.com/iliyan-trifonov/notepads-ionic/blob /master/www/js/services.js#L33 。
移动应用发送带有以下请求的令牌:
The mobile app sends the token with the request:
notepads: {
list: function() {
return $http({
url: apiBase + '/notepads?insidecats=1' + '&token=' + User.get().accessToken/*gets the token from the local storage*/,
method: 'GET',
cache: false
});
},
这是一个Ionic / Angular / Cordova应用程序。通过移动应用程序登录Facebook会启动手机上安装的Facebook应用程序,或打开弹出窗口以登录Facebook。然后回调将Facebook用户的ID和访问令牌返回到我的移动应用程序。
It's an Ionic/Angular/Cordova app. The Facebook login from the mobile app starts the Facebook app installed on your phone or opens a popup to login in Facebook. Then a callback returns the Facebook user's id and access token to my mobile app.
fbgraph npm模块: https://github.com/criso/fbgraph
The fbgraph npm module: https://github.com/criso/fbgraph
这篇关于使用Passport和OAuth2 +社交网络的NodeJS REST身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!