且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 Passport 和 OAuth2 + 社交网络的 NodeJS REST 身份验证

更新时间:2022-12-06 21:52:50

我将 Facebook 登录用于我自己的 我的记事本应用程序在这里.我开始时将应用程序用作网页,但登录后的通信仍将通过 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.

然后我决定创建一个 同一应用的移动版本,它将使用应用程序接口.我决定这样做:移动应用程序通过 Facebook 登录并将 Facebook 用户 ID 和 FB 访问令牌发送到 API,API 调用 Facebooks 的 API 来验证这些参数,如果成功注册新用户(或登录现有的一个)在我的应用程序的数据库中,为此用户创建一个自定义令牌并将其返回到移动应用程序.移动应用从这里发送此自定义令牌以使用 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 中的 auth(使用 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...

noreferr="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