2015-07-13 3 views
0

Кто-нибудь успешно прошел навигацию Jawbone's OAuth2.0 authentication для своего REST API?Jawbone API OAuth access_token обработка с node.js (экспресс и паспорт)

Я не могу понять, как получить доступ и отправить authorization_code для того, чтобы получить access_token (шаги 4 & 5 в Jawbone API Authorization Documentation). Я хочу повторно использовать access_token для последующих вызовов (AJAX-стиль) и не просить пользователя повторно авторизоваться каждый раз.

Для каждого вызова API (get.sleeps) требуется полная обратная связь процесса auth, включая эту повторную авторизацию, чтобы получить authorization_token (снимок экрана). Ибо Jawbone и Passport Документация расплывчата в этом вопросе.

enter image description here

Мой стек включает в себя, node.js, то jawbone-up NPM, express.js и passport.js. Стратегия паспортов для Jawbone, похоже, работает правильно, когда я возвращаю действительные данные.

jawbone-up NPM явно не помогает поддерживать сеанс (access_token), говоря: «Эта библиотека не помогает в получении access_token через OAuth ...»

ВОПРОС: Как я на самом деле использовать OAuth access_token в вызов API? Может ли кто-нибудь показать мне код для этого?

Благодаря

var dotenv = require('dotenv').load(), 
    express = require('express'), 
    app = express(), 
    ejs = require('ejs'), 
    https = require('https'), 
    fs = require('fs'), 
    bodyParser = require('body-parser'), 
    passport = require('passport'), 
    JawboneStrategy = require('passport-oauth').OAuth2Strategy, 
    port = 5000, 
    jawboneAuth = { 
     clientID: process.env.JAWBONE_CLIENT_ID, 
     clientSecret: process.env.JAWBONE_CLIENT_SECRET, 
     authorizationURL: process.env.JAWBONE_AUTH_URL, 
     tokenURL: process.env.JAWBONE_AUTH_TOKEN_URL, 
     callbackURL: process.env.JAWBONE_CALLBACK_URL 
    }, 
    sslOptions = { 
     key: fs.readFileSync('./server.key'), 
     cert: fs.readFileSync('./server.crt') 
    }; 
    app.use(bodyParser.json()); 
    app.use(express.static(__dirname + '/public')); 
    app.set('view engine', 'ejs'); 
    app.set('views', __dirname + '/views'); 

// ----- Passport set up ----- // 
app.use(passport.initialize()); 

app.get('/', 
    passport.authorize('jawbone', { 
     scope: ['basic_read','sleep_read'], 
     failureRedirect: '/' 
    }) 
); 

app.get('/done', 
    passport.authorize('jawbone', { 
     scope: ['basic_read','sleep_read'], 
     failureRedirect: '/' 
    }), function(req, res) { 
     res.render('userdata', req.account); 
    } 
); 

passport.use('jawbone', new JawboneStrategy({ 
    clientID: jawboneAuth.clientID, 
    clientSecret: jawboneAuth.clientSecret, 
    authorizationURL: jawboneAuth.authorizationURL, 
    tokenURL: jawboneAuth.tokenURL, 
    callbackURL: jawboneAuth.callbackURL 
}, function(token, refreshToken, profile, done) { 
    var options = { 
      access_token: token, 
      client_id: jawboneAuth.clientID, 
      client_secret: jawboneAuth.clientSecret 
     }, 
     up = require('jawbone-up')(options); 

    up.sleeps.get({}, function(err, body) { 
     if (err) { 
      console.log('Error receiving Jawbone UP data'); 
     } else { 
     var jawboneData = JSON.parse(body).data; 
     console.log(jawboneData); 
     return done(null, jawboneData, console.log('Jawbone UP data ready to be displayed.')); 
     } 
    }); 
})); 
// HTTPS 
var secureServer = https.createServer(sslOptions, app).listen(port, function(){ 
    console.log('UP server listening on ' + port); 
}); 

ответ

0

Вы не были слишком далеко, вы уже получали токен.Чтобы сделать работу вашего кода, необходимо выполнить несколько шагов:

Добавить концепцию «сеанса», которая существует из запроса для запроса в качестве глобальной переменной. Когда вы делаете полное веб-приложение, используйте экспресс-сессии и паспортные сессии и внедряйте управление пользователями. Но сейчас мы просто добавляем глобальное значение для одного состояния пользователя.

var demoSession = { 
    accessToken: '', 
    refreshToken: '' 
}; 

Передача объекта пользователя в done() JawboneStrategy. Это связано с тем, что функция «авторизации» паспорта ожидает, что пользователь будет присутствовать на сессии. Он присоединяет результаты авторизации этому пользователю. Поскольку мы просто тестируем API, просто передаем пустой пользователь.

Используйте специальную страницу для отображения данных "/ data". Добавьте маршрут, чтобы отделить auth от отображения сервиса.

app.get('/done', passport.authorize('jawbone', { 
     scope: ['basic_read','sleep_read'], 
     failureRedirect: '/' 
    }), function(req, res) { 
     res.redirect('/data'); 
    } 
); 

Последний раз API Jawbone Up sleeps немного сложнее. Вы должны добавить строку ГГГГММДДА на запрос:

app.get('/data', function(req, res) { 

    var options = { 
     access_token: demoSession.accessToken, 
     client_id: jawboneAuth.clientID, 
     client_secret: jawboneAuth.clientSecret 
    }; 
    var up = require('jawbone-up')(options); 

    // we need to add date or sleep call fails 
    var yyyymmdd = (new Date()).toISOString().slice(0, 10).replace(/-/g, ""); 
    console.log('Getting sleep for day ' + yyyymmdd); 

    up.sleeps.get({date:yyyymmdd}, function(err, body) { 
     if (err) { 
      console.log('Error receiving Jawbone UP data'); 
     } else { 
      try { 
       var result = JSON.parse(body); 
       console.log(result); 
       res.render('userdata', { 
        requestTime: result.meta.time, 
        jawboneData: JSON.stringify(result.data) 
       }); 
      } 
      catch(err) { 
       res.render('userdata', { 
        requestTime: 0, 
        jawboneData: 'Unknown result' 
       }); 
      } 

     } 
    }); 
}); 

Я создал суть, которая работает для меня здесь Thats основан на коде: https://gist.github.com/longplay/65056061b68f730f1421

0

Маркер доступа Jawbone истекает в года, так что вы определенно не должны повторно проверить подлинность пользователя каждый раз. Также вам предоставляется refresh_token, так что при необходимости вы можете обновить токен доступа.

После того, как у вас есть access_token, вы должны его хранить где-нибудь, желательно в какой-то базе данных или в хранилище файлов для последующего использования, тогда вы используете этот токен для каждого запроса, сделанного в Jawbone REST API.

челюстной вверх модуль использует request внутри, так что я собираюсь показать вам, как сделать запрос с ним (он должен быть в значительной степени то же самое с любым другим модулем).

Вот как вы можете получить профиль пользователя (самый основной API вызова):

var request = require('request') 
request.get({ 
    uri:'https://jawbone.com/nudge/api/v.1.1/users/@me', 
    auth:{bearer:'[ACCESS_TOKEN]'}, 
    json:true 
}, function (err, res, body) { 
    // body is a parsed JSON object containing the response data 
}) 

Там есть еще один модуль, который называется Purest, который также использует запрос внутренне, но скрывает некоторые сложности вокруг использования REST API. Вот как тот же самый запрос будет выглядеть, как с помощью этого модуля:

var Purest = require('purest') 
var jawbone = new Purest({provider:'jawbone'}) 
jawbone.get('users/@me', { 
    auth:{bearer:'[ACCESS_TOKEN]'} 
}, function (err, res, body) { 
    // body is a parsed JSON object containing the response data 
}) 

В качестве альтернативы для аутентификации пользователя (получение access_token), вы можете использовать другой модуль, называемый Grant, который я лично использую, но ни один должен работать.

+0

Симы, я не встречал эти модули раньше, но начнет чтение. У вас есть образец кода для обработки истекшего «access_token»? Это, вероятно, моя собственная неопытность, но я считаю документы Passportjs и Jawbone довольно бесполезными .... – Colin

+0

Используя запрос 'request.post ({uri: 'https: //jawbone.com/auth/oauth2/token', form: {grant_type: 'refresh_token', refresh_token: '..', client_id: '..', client_secret: '..'}}, function (e, r, b) {}) ':) – simo

+0

Simo, мне плохо поскольку это был хороший ответ, но я не мог заставить Гранта работать. Я продолжал застревать с ошибкой «invalid_redirect». Я могу опубликовать еще один вопрос об этом, хотя, если я смогу заставить это работать, это очень чистый и элегантный модуль. – Colin