Meteor RESTful身份验证。这是否可行?

6
我已经搜索了很多,但无法找到一个令人满意的答案来回答这个问题。
我有一个Meteor网站,用户登录并创建内容。 我还想创建一个手机应用程序,可以与网站交互,并希望用户登录到手机应用程序并访问网站上的相同内容。 这很正常。
我已经创建了一个基本的REST API来使用meteorite包HTTP.publish访问集合。 它可以在没有任何用户信息(无身份验证)的情况下工作,但现在我想在GET方法和集合的Meteor.allow规则中使用userId来访问当前用户。
因此,我目前正在努力告诉meteor在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。
我的问题是:
1.令牌是否针对客户端创建(例如使用主机URL进行散列)?
2.bcrypt是否更改了X-Auth-Token的使用方式? 如果没有,那么我在curl命令中做错了什么。
3.DDP是否是创建有效令牌的唯一方法,还是我可以创建一个API调用,在服务器上创建令牌,即使现在只传递纯文本凭据?
例如/api/login?user=shane&pwd=qwerty =>返回我可以在curl请求中使用的token
我真的被卡住了,所以任何指向正确方向的东西都将不胜感激。 我还注意到http.publish尚未创建登录/注销方法,因此可能并不容易。
3个回答

4
几天前,我开始开发一个类似认证的应用程序。我发现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 }

在每个向服务器发送的请求中,将登录令牌和用户ID作为标头包含在内。
你应该查看它:
文档:http://github.differential.io/reststop2/ Github:https://github.com/Differential/reststop2

2
看完 auth.js 后,我明白了正在发生的事情以及如何创建新的令牌。我没有意识到的是,每个基于 REST 的 API 都有自己的身份验证方式和设置 this.userId 的方法。http-methods:使用 token 查询参数 RESTstop:使用 loginTokenuserId 参数(还有头部版本) fileCollection:使用头部 X-Auth-TokenMeteor 本身使用 DDP 连接来获取 userId,这是我们在 REST 中没有的。这很有用。如果所有 REST 包都能遵守一个单一的方法就好了……我可以做梦了。 - Shane

1
我发布了一个用于在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"

1
除了其他答案中提到的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可能是更好的选择,至少在我的看法中是这样的。 - Shane
通常情况下,您可以使用用户名/密码通过一个端点(例如/api/login)进行身份验证,然后该端点返回一个令牌,该令牌在每个后续调用中通过“Authentication”标头使用。 - Andrei Karpushonak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接