【问题标题】:node.js API authenticationnode.js API 认证
【发布时间】:2016-04-03 22:59:26
【问题描述】:

我正在开发一个与 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 令牌创建和管理我的 api_token。

【问题讨论】:

    标签: node.js facebook api authentication


    【解决方案1】:

    如果有人感兴趣,我终于实现了第二个解决方案。很简单,做的工作!

    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;
    }
    

    欢迎任何反馈。

    问候

    【讨论】:

      猜你喜欢
      • 2017-08-19
      • 2016-06-19
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 2021-10-25
      • 2014-08-13
      • 2015-08-08
      • 1970-01-01
      相关资源
      最近更新 更多