Аутентификация Meteor RESTful. Возможно ли это?

#rest #authentication #meteor

#rest #аутентификация #meteor

Вопрос:

Я искал вокруг, но не могу найти удовлетворительного ответа на этот вопрос.

У меня есть веб-сайт meteor, где пользователи входят в систему и создают контент. Я также хочу создать приложение для телефона, способное взаимодействовать с веб-сайтом, и я хочу, чтобы пользователи входили в приложение для телефона и получали доступ к тому же контенту на веб-сайте. Довольно нормально.

Я создал базовый REST API для доступа к коллекциям с использованием пакета meteorite HTTP.publish . Она работает без какой-либо информации о пользователе (без авторизации), но теперь я хочу использовать userId один из методов GET и в Meteor.разрешить правилам коллекций доступ к текущему пользователю.

Итак, в настоящее время я пытаюсь понять, как сообщить meteor в запросе REST идентификатор пользователя, даже во время простого тестирования. Я думал, что смогу получить 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=shaneamp;pwd=qwerty => return token я могу использовать в запросе curl.

Я действительно застрял в этом, поэтому буду признателен за все, что указывает мне в правильном направлении. Я также отмечаю, что http.publish еще не созданы методы входа / выхода, поэтому, возможно, это не так просто.

Ответ №1:

Несколько дней назад я запустил приложение с аналогичными требованиями к аутентификации. Я обнаружил, что RESTstop2 от Differential недавно, в версии 0.6.0, обновил свою поддержку аутентификации для поддержки недавно добавленного шифрования Bcrypt в Meteor.

Вы просто отправляете имя пользователя и пароль либо в виде параметров URL, либо в теле, подобном этому:

 curl --data "password=testpasswordamp;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

Комментарии:

1. Отлично, после прочтения auth.js я понимаю, что происходит, и как создаются новые токены. Чего я не оценил, так это того, что каждый из API на основе REST имеет свой собственный способ аутентификации и настройки this.userId . http-методы: использует параметр token запроса RESTstop: использует loginToken и userId параметры (также версии заголовка) FileCollection: использует заголовок X-Auth-Token Сам Meteor использует DDP-соединение для получения userId того, чего у нас нет с REST. Это было полезно. Было бы неплохо, если бы все пакеты REST могли соответствовать одному методу… Я могу мечтать.

Ответ №2:

Другой вариант (помимо RESTstop2, упомянутого в другом ответе), вы можете использовать автономный пакет api-password от Atmosphere, который выполняет именно то, что вам нужно: аутентифицировать вызовы 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'
  }
  

Комментарии:

1. Это здорово, если вы просто хотите передавать имя пользователя и пароль с каждым запросом, с чем многие люди согласятся. Должно быть нормально через https, я думаю. Однако, если вы хотите реализовать службу входа в систему и передавать обратно токен для будущих запросов, то, вероятно, подойдет RESTStop2. По крайней мере, в моем варианте.

2. Обычно вы проходите аутентификацию с использованием имени пользователя / пароля, используя одну конечную точку (например, /api/login), затем эта конечная точка возвращает токен, который используется в каждом последующем вызове через заголовок ‘Authentication’

Ответ №3:

Я опубликовал пакет для написания REST API в Meteor 0.9.0 , который поддерживает аутентификацию. Он предназначен для замены RestStop2 (принятый ответ) теперь, когда он устарел и имеет аналогичный API:

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

Она была вдохновлена RestStop2 и построена с использованием серверной маршрутизации Iron Router.

ОБНОВЛЕНИЕ: я просто хотел включить пример кода для всех, кто найдет это. Это пример быстрого запуска Restivus из GitHub README:

 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"