使用Passport和OAuth2 +社交网络的NodeJS REST身份验证 [英] NodeJS REST authentication using Passport and OAuth2 + social network

查看:108
本文介绍了使用Passport和OAuth2 +社交网络的NodeJS REST身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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...

https://github.com/iliyan-trifonov/ notepads-nodejs-angularjs-mongodb-bootstrap / blob / 6617a5cb418ba8acd6351ef9a9f69228f1047154 / src / routes / users.js#L46

用户模型:

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

https://github.com/iliyan-trifonov/notepads-nodejs-angularjs-mongodb-bootstrap/blob/ master / src / models / user.js#L9

移动应用程序中的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屋!

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