与parse-server和auth0进行自定义身份验证集成

时间:2016-06-28 07:32:30

标签: ios authentication oauth parse-server auth0

我想将auth0.com与开源解析服务器结合使用。

我目前的方法是通过iOS的Lock库使用标准登录从auth0获取令牌。使用该令牌,我想在我的解析服务器上调用一个自定义身份验证方法,该方法检查令牌是否有效以及是否将登录用户。

我的问题是几乎没有关于为parse-server编写自定义oauth的文档。

到目前为止,我已将此代码用于我的自定义身份验证。

var Parse = require('parse/node').Parse;

function validateAuthData(authData, options) {
  console.log('validateAuthData()');
  return new Promise((resolve, reject) => {
    try {
      var decoded = jwt.verify(authData.access_token, opions.sharedSecret);
      if (authData.id === decoded.sub) {
        resolve({});
      }
      throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Unauthorized');
    } catch(e) {
      throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, e.message);
    }
  });
}

function validateAppId(appIds, authData) {
  console.log('validateAppId()');
  return Promise.resolve();
}

module.exports = {
  validateAppId: validateAppId,
  validateAuthData: validateAuthData
};

但是,它不起作用,我也不明白如何使用此代码来验证特定用户。解析服务器是否进行数据库查找以将特定身份验证数据与特定用户相匹配?另外,如何使用自定义身份验证注册新用户。当用户尝试登录但他在我的解析数据库中还没有存在时会发生什么?

替代似乎是this,使用规则auth0.com。有什么区别以及该规则将如何运作?我对身份验证和oauth以及jwt的经验很少。

最后,我使用this从我的iOS客户端调用我的自定义身份验证。然而,这也不起作用,但我不确定它是由于iOS部分还是因为我的自定义身份验证还没有工作。

总之,我遇到的问题似乎相当容易。我想使用auth0作为我的身份验证提供程序,我想将它集成为解析服务器,因为我非常感谢解析和客户端sdk的便利性。我相当肯定会有更多人遇到类似的问题,但是我没有找到关于如何正确执行此操作的明确资源。

更多链接

1 个答案:

答案 0 :(得分:1)

迟来的答案,但是我正在解决相同的问题,并且遇到了这篇文章:

Auth0具有您可以应用的规则,该规则在登录发生时运行。我从https://github.com/auth0/rules/blob/master/src/rules/parse.js修改了他们的示例一,将API端点提取到了常量中。

function(user, context, callback) {
  // run this only for the Parse application
  // if (context.clientID !== 'PARSE CLIENT ID IN AUTH0') return callback(null, user, context);

  const request = require('request');

  const MY_API = 'https://subdomian.back4app.io';
  const PARSE_APP_ID = '*********';
  const PARSE_API_KEY = '**********';
  const PARSE_USER_PASSWORD = 'REPLACE_WITH_RANDOM_STRING'; // you can use this to generate one http://www.random.org/strings/

  const username = user.email || user.name || user.user_id; // this is the Auth0 user prop that will be mapped to the username in the db

  request.get({
      url: `${MY_API}/login`,
      qs: {
        username: username,
        password: PARSE_USER_PASSWORD
      },
      headers: {
        'X-Parse-Application-Id': PARSE_APP_ID,
        'X-Parse-REST-API-Key': PARSE_API_KEY
      }
    },
    function(err, response, body) {
      if (err) return callback(err);

      // user was found, add sessionToken to user profile
      if (response.statusCode === 200) {
        context.idToken[`${MY_API}/parse_session_token`] = JSON.parse(body).sessionToken;
        return callback(null, user, context);
      }

      // Not found. Likely the user doesn't exist, we provision one
      if (response.statusCode === 404) {
        request.post({
            url: `${MY_API}/users`,
            json: {
              username: username,
              password: PARSE_USER_PASSWORD
            },
            headers: {
              'X-Parse-Application-Id': PARSE_APP_ID,
              'X-Parse-REST-API-Key': PARSE_API_KEY,
              'Content-Type': 'application/json'
            }
          },
          function(err, response, body) {
            if (err) return callback(new Error('user already exists'));

            // user created, add sessionToken to user profile
            if (response.statusCode === 201) {
              context.idToken[`${MY_API}/parse_session_token`] = body.sessionToken;
              return callback(null, user, context);
            }
            return callback(new Error(username + ' The user provisioning returned an unknown error. Body: ' + JSON.stringify(body)));
          });
      } else {
        return callback(new Error('The login returned an unknown error. Status: ' + response.statusCode + ' Body: ' + body));
      }
    });
}

我正在用JS编写SPA,因此我有一些处理Auth0登录的客户端代码(用自己的解析服务器的API地址替换'https://subdomian.back4app.io'-与上面使用的值相同Auth0规则)。注意Parse.User.become函数,该函数将在Auth0规则中创建的会话ID分配给当前的分析用户:

handleAuthentication() {
  this.auth0.parseHash((err, authResult) => {
    if (authResult && authResult.accessToken && authResult.idToken) {
      this.setSession(authResult);
      Parse.User.become(authResult.idTokenPayload['https://subdomian.back4app.io/parse_session_token']);
      history.replace('/');
    } else if (err) {
      history.replace('/home');
      console.log(err);
    }
  });
}