node.js API身份验证

时间:2016-04-02 17:30:58

标签: node.js facebook api authentication

我正在开发一个与nodejs后端服务器REST API通信的iOS应用程序,我正在考虑API身份验证。

我希望只有iOS应用程序才能与API通信。

在iOS应用程序端,用户通过Facebook登录进行身份验证。因此,他们在iOS应用程序上进行身份验证后获得fb access_token和fbid。

对于API身份验证,我打算这样做:

  • 当用户登录iOS应用程序时,使用fb access_token和fbid调用/ api / auth;
  • 如果用户是新用户,我会为此用户创建一个随机的api_token,将其存储到用户数据库中,然后将其发送回iOS应用程序;
  • 如果用户已经在数据库中,我刷新数据库中的fb access_token和api_token并将其发送回iOS应用程序;
  • 对于每个API调用,我将api_token作为POST参数提供,在服务器端,我通过在执行API调用之前获取数据库来检查它是否有效。

我错过了足够安全的东西吗?

非常欢迎任何反馈或改进。

此致

编辑:

另一种方式如下:

  • 开/ api / auth如果fb access_token仍然有效,我检查了FacebookB API(/ me);
  • 如果不是,我拒绝认证;
  • 如果是,我使用JSON Web Tokens创建和管理我的api_token。

1 个答案:

答案 0 :(得分:0)

如果有人有兴趣,我终于实施了第二个解决方案。非常简单,做好工作!

config.js

module.exports = {
    'secret': 'apisupersecrethere',
};

route.js

var config = require('./config');
app.set('api_secret', config.secret);
api = express.Router();

// function that checks the api_token
api.use(function(req, res, next) {
    var token = req.headers['x-access-token'];
    if (token) {
        jwt.verify(token,app.get('api_secret'),function(err, decoded) {
            if (err) {
                return res.json({
                    success: false,
                    message: 'Failed to authenticate token.'
                });
            } else {
                req.decoded = decoded;
                next();
            }
        });
    } else {
        return res.status(403).send({ 
            success: false, 
            message: 'No token provided.'
        });
    }
});

// route protected by the authentication
router.use('/users', api);

// authentication route
router.post('/auth', function(req, res) {
    verifyFacebookUserAccessToken(req.body.access_token).
        then(function(user) {
            var token = jwt.sign(user, app.get('api_secret'), {
                expiresIn: 1440*60 // expires in 24 hours
            });
            res.status(200).json({
                success: true,
                message: "Authentication success!",
                token: token
            });
        }, function(error) {
            res.status(401).json({
                success: false,
                message: error.message
            });
        }).
        catch(function(error){
            res.status(500).json({
                success: false,
                message: error.message
            });
        });
    });

// Call facebook API to verify the token is valid
function verifyFacebookUserAccessToken(token) {
    var deferred = Q.defer();
    var path = 'https://graph.facebook.com/me?access_token=' + token;
    request(path, function (error, response, body) {
        var data = JSON.parse(body);
        if (!error && response && response.statusCode && response.statusCode == 200) {
            var user = {
                facebookUserId: data.id,
                username: data.username,
                firstName: data.first_name,
                lastName: data.last_name,
                email: data.email
        };
            deferred.resolve(user);
        }
        else {
            deferred.reject({
                code: response.statusCode,
                message: data.error.message
            });
        }
    });
    return deferred.promise;
}

欢迎任何反馈。

此致