Everyauth и доступ к (твиттеру) данных oauth из findUserById
Я пытаюсь использовать everyauth
в express
аутентифицировать пользователей на сайте, позволяющем добавлять текстовые комментарии к изображениям. В настоящее время я использую api twitter oauth для аутентификации своих пользователей.
Сейчас я пытаюсь создать пользовательскую базу данных, которая позволяет мне поддерживать несколько способов входа в систему, связанных с одной записью в CouchDB. У меня возникают проблемы, когда я хочу добавить нового пользователя в БД, когда он первоначально подключается через твиттер. Код моего findUserById
гласит следующее:
everyauth.everymodule.findUserById (userId, callback) ->
users.findById userId, (err,res) ->
if res.id
# id returned, so there is an entry in the DB
callback null, res
else
# no entry in the DB, add a new one
users.saveById JSON.stringify(userId), {"name":"test"}, (saveErr, saveRes) ->
callback null, saveRes
everyauth.twitter
.consumerKey(config.twitterConsumerKey)
.consumerSecret(config.twitterConsumerSecret)
.findOrCreateUser((session, token, secret, user) ->
promise = @.Promise().fulfill user
).redirectPath '/'
findById
а также saveById
методы cradle
объект, который запрашивает БД, userId
обеспечивается всем, как кажется.
Моя проблема заключается в {"name":"test"}
часть. Это место, где я хочу добавить данные из req.session.auth.twitter
возражать против БД. Как я могу получить доступ к этим значениям из findUserById
функционировать?
Это вообще возможно? Есть ли другой подход? Я смотрю на функцию findOrCreateUser, но я понятия не имею, как это изменить, не ломая мое приложение - я еще не понимаю концепцию Обещания.
2 ответа
Поигравшись дальше, я нашел решение проблемы, которую я поставил. Чтобы получить доступ к полным пользовательским данным, которые передаются с помощью запроса OAuth относительно структуры Promise для каждого элемента aauth, вызов everyauth.twitter должен выглядеть следующим образом:
everyauth.twitter
.consumerKey(config.twitterConsumerKey)
.consumerSecret(config.twitterConsumerSecret)
.findOrCreateUser((session, token, secret, user) ->
users.findByTwitterId user.id, (err,res) ->
if res.id
user=res.value
else
newUser = {id:user.id,name:user.name,twitter:user}
user = newUser
users.saveById JSON.stringify(user.id), user, (saveErr, saveRes) ->
promise = @.Promise().fulfill user
).redirectPath '/'
findByTwitterId
Вызов - это функция, которая запрашивает CouchDB для просмотра документов, содержащих twitter.id
поле.
req.user
Объект заполняется этим:
everyauth.everymodule.findUserById (userId, callback) ->
users.findByTwitterId userId, (err,res) ->
if res.id
callback null, res.value
else
callback null, null
Я не могу дать каких-либо указаний о том, как решить вашу проблему, используя Everyauth Тем не менее, вы рассматривали возможность использования паспорта для аутентификации?
Я разработчик Passport, поэтому не стесняйтесь задавать мне любые вопросы. Я написал это после того, как попробовал все и все так же разочаровался в предложенном контроле потока, включая обещания.
Passport имеет простой механизм для обработки входа с помощью Twitter (или любого другого поставщика OAuth), используя модуль passport-twitter:
passport.use(new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
},
function(token, tokenSecret, profile, done) {
User.findOrCreate({ twitterId: profile.id }, function (err, user) {
return done(err, user);
});
}
));
В рамках обратного вызова проверки (как он известен) у вас есть полный доступ к токену и токену, выпущенному Twitter, а также к полному профилю Twitter. Вы можете использовать эту информацию, чтобы найти или создать пользователя в вашей базе данных.
Запуск входа в систему так же прост, как добавление нескольких маршрутов в ваше приложение:
app.get('/auth/twitter', passport.authenticate('twitter'));
app.get('/auth/twitter/callback',
passport.authenticate('twitter', { successRedirect: '/',
failureRedirect: '/login' }));