【问题标题】:Meteor RESTful Authentication. Is it possible?Meteor RESTful 身份验证。可能吗?
【发布时间】:2016-07-26 20:51:01
【问题描述】:

我已经四处搜索,但找不到这个问题的满意答案。

我有一个流星网站,用户可以在其中登录并创建内容。我还想创建一个能够与网站交互的手机应用程序,我希望用户登录手机应用程序并访问网站上的相同内容。很正常。

我创建了一个基本的 REST API,用于使用陨石包 HTTP.publish 访问集合。它在没有任何用户信息(无身份验证)的情况下工作,但现在我想使用 GET 方法的 userId 和集合的 Meteor.allow 规则来访问当前用户。

所以我目前正在努力解决如何在 REST 请求中告诉流星,用户的 id,即使只是在测试时也是如此。我想我可以在浏览器中获取有效用户的Accounts._storedLoginToken 并使用它来测试 CURL。类似的东西

curl -H "X-Auth-Token: asdklfjasldfjlsadkjf" -H "Content-Type: application/json" -d '{"name":"A Name","description":"Testing description"}' http://localhost:3000/api/places

我试过这个,但不高兴,我得到了一个 403,这至少是好的。

我的问题是这样的:

  • 是特定于客户端创建的令牌(即使用主机 url 或其他东西进行哈希处理)吗?
  • bcrypt 是否改变了X-Auth-Token 的使用方式?如果不是,我在 curl 命令中做错了什么。
  • DDP 是创建有效令牌的唯一方法,还是我可以创建一个 API 调用来在服务器上创建一个令牌,即使现在只是传递纯文本凭据?

例如/api/login?user=shane&pwd=qwerty => return token 我可以在 curl 请求中使用。

我真的坚持这一点,所以任何指向我正确方向的东西都将不胜感激。我还注意到http.publish 还没有创建登录/注销方法,所以可能没那么容易。

【问题讨论】:

    标签: rest authentication meteor


    【解决方案1】:

    几天前,我开始开发一个对身份验证有类似要求的应用。我发现Differential 的RESTstop2 最近在0.6.0 版本中升级了他们的身份验证支持以支持Meteor 中新添加的Bcrypt 加密。

    您只需将用户名和密码作为 URL 参数或正文发送,如下所示:

    curl --data "password=testpassword&user=test" http://localhost:3000/api/login/
    

    并且服务器将返回以下内容(如果凭据正确):

    { success: true, loginToken: "f2KpRW7KeN9aPmjSZ", userId: fbdpsNf4oHiX79vMJ }
    

    在您向服务器发出的每个请求中,包括 loginToken 和 userId 作为标头。

    你应该检查一下:

    文档: http://github.differential.io/reststop2/

    Github: https://github.com/Differential/reststop2

    【讨论】:

    • 太好了,在阅读auth.js 之后,我了解正在发生的事情以及如何创建新令牌。我没有意识到的是,每个基于 REST 的 API 都有自己的验证和设置 this.userId 的方式。 http-methods:使用 token 查询参数 RESTstop:使用 loginTokenuserId 参数(也是标头版本) fileCollection:使用标头 X-Auth-Token Meteor 本身使用 DDP 连接来获取 userId,我们不这样做有 REST。这很有用。如果所有 REST 包都可以符合一个方法,那就太好了……我可以梦想。
    【解决方案2】:

    另一个选项(除了其他答案中提到的 RESTstop2 之外),您可以使用 Atmosphere 中的独立 api-password 包,这正是您需要的:在服务器端验证 REST 调用。 它也支持 Meteor 0.8.2(带有 bcrypt)。

    服务器端示例

      try {
        if (ApiPassword.isPasswordValid(username, password)) {
          console.log('password is valid for this user');
        } else {
          console.log('password is not valid');
        }
    
      } catch (exc) {
          console.log(exc.message);
          // possible causes: 'User is not found', 'User has no password set'
      }
    

    【讨论】:

    • 如果您只想在每个请求中传递用户名和密码,这很好,很多人都会接受。我猜应该可以通过https。但是,如果您想实现登录服务,并为将来的请求传回令牌,那么 RESTStop2 可能是要走的路。至少在我看来。
    • 通常您使用用户名/密码使用一个端点(如 /api/login)进行身份验证,然后此端点返回一个令牌,该令牌用于通过“身份验证”标头进行的每次后续调用
    【解决方案3】:

    我发布了一个用于在 Meteor 0.9.0+ 中编写支持身份验证的 REST API 的包。它旨在取代 RestStop2 (已接受的答案),因为它已被弃用,并且具有类似的 API:

    https://github.com/krose72205/meteor-restivus

    它的灵感来自 RestStop2,并使用 Iron Router 的服务器端路由构建。

    更新:我只是想为找到此内容的任何人提供一个代码示例。这是来自 GitHub README 的 Restivus 快速入门示例:

    Items = new Mongo.Collection 'items'
    
    if Meteor.isServer
    
      # API must be configured and built after startup!
      Meteor.startup ->
    
        # Global API configuration
        Restivus.configure
          useAuth: true
          prettyJson: true
    
        # Generates: GET, POST, DELETE on /api/items and GET, PUT, DELETE on
        # /api/items/:id for Items collection
        Restivus.addCollection Items
    
        # Generates: GET, POST on /api/users and GET, DELETE /api/users/:id for
        # Meteor.users collection
        Restivus.addCollection Meteor.users,
          excludedEndpoints: ['deleteAll', 'put']
          routeOptions:
            authRequired: true
          endpoints:
            post:
              authRequired: false
            delete:
              roleRequired: 'admin'
    
        # Maps to: /api/posts/:id
        Restivus.addRoute 'posts/:id', authRequired: true,
          get: ->
            post = Posts.findOne @urlParams.id
            if post
              status: 'success', data: post
            else
              statusCode: 404
              body: status: 'fail', message: 'Post not found'
          post:
            roleRequired: ['author', 'admin']
            action: ->
              post = Posts.findOne @urlParams.id
              if post
                status: "success", data: post
              else
                statusCode: 400
                body: status: "fail", message: "Unable to add post"
          delete:
            roleRequired: 'admin'
            action: ->
              if Posts.remove @urlParams.id
                status: "success", data: message: "Item removed"
              else
                statusCode: 404
                body: status: "fail", message: "Item not found"
    

    【讨论】:

      猜你喜欢
      • 2012-10-01
      • 2011-11-28
      • 2013-08-21
      • 2010-11-28
      • 2011-01-12
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多