API Battle.net возвращает ошибку 401 при использовании токена OAuth
Я использую Nodejs с экспрессом в API Battle.net для генерации Oauth-токена. https://develop.battle.net/documentation/guides/using-oauth
Генерация токена сама по себе работает, так как он возвращает мне токен. Но когда я использую код, чтобы сделать запрос к их API, например:
Я получаю 401 Unauthorized Error Response, журнал отладки:
{ url:
'https://eu.api.blizzard.com/wow/guild/Malfurion/The%20new%20Dimension?fields=members&locale=de_DE&access_token=HEREISMYTOKEN',
status: 401,
statusText: 'Unauthorized',
headers: Headers { [Symbol(map)]: [Object] } }
Я пытаюсь получить членов гильдии через fetch().
Я уже попробовал:
Создание нового приложения (с новым Client Secret и ID)
установка каждого возможного URL обратного вызова в настройках battle.net:
https://localhost/ http://localhost/ https://localhost/ http://localhost:443/ https://localhost/auth/bnet/callback http://localhost/auth/bnet/callback https://localhost/auth/bnet/callback http://localhost:443/auth/bnet/callback
создание токена вручную путем "тестирования API" ( https://develop.battle.net/documentation/api-reference/world-of-warcraft-community-api), где вы вводите свой идентификатор клиента и секрет, а затем получить временный токен. Это работает, также в моем приложении.
Вы можете сравнить ответ этих двух URL (просто используйте ваш браузер):
Первый (создается в моем приложении): https://eu.api.blizzard.com/wow/guild/Blackmoore/The%20new%20Dimension?fields=members&locale=de_DE&access_token=EU7XD8E4K9IAJKBGJSP3MDBLAVCIU2BYXS
Второе (созданное для тестирования API на веб-сайте battle.net, где вы вводите данные о клиентах и секретные данные для проверки API): https://eu.api.blizzard.com/wow/guild/Blackmoore/The%20new%20Dimension? поля = члены и локали = de_DE & access_token = US23su4g0hAeS5w3EUCkKA9MJPgJ8k8bzV
КОД
server.js, простое экспресс-приложение
var BNET_ID = "MYID";
var BNET_SECRET = "MYSECRET";
...
// Use the BnetStrategy within Passport.
passport.use(
new BnetStrategy(
{ clientID: BNET_ID,
clientSecret: BNET_SECRET,
scope: "wow.profile sc2.profile",
callbackURL: "https://localhost/",
region: "eu" },
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
})
);
// bnet auth routes
app.get('/auth/bnet', passport.authenticate('bnet'));
app.get('/auth/bnet/callback',
passport.authenticate('bnet', { failureRedirect: '/' }),
function(req, res){
res.redirect('/');
});
controller.js
...
const res = await fetch(`https://eu.api.blizzard.com/wow/guild/${servers[iterator]}/The new Dimension?fields=members&locale=de_DE&access_token=${thetoken}`).then((res) => {
res.json();
// for debugging, shows 401 Error
console.log(res);
});
...
Я на самом деле ожидаю такой ответ, потому что он работает с использованием временного токена:
status: 200 OK
body: {
"lastModified": 1546676373000,
"name": "The new Dimension",
"realm": "Blackmoore",
"battlegroup": "Glutsturm / Emberstorm",
"level": 25,
"side": 0,
"achievementPoints": 1005,
"members":
(......)
}
Мне удалось решить проблему!
Очень, очень хакерский, но мне удалось решить проблему, взломав промежуточное программное обеспечение oauth callback следующим образом: установите мой используемый API-токен в req.user.token.
app.get('/auth/bnet/callback',
passport.authenticate('bnet', { failureRedirect: '/?error' }),
function(req, res) {
req.session.bnettoken = req.user.token;
res.redirect('/');
}
);
Я подозреваю, что "код" или "токен" также используется в моем SessionStorage (экспресс-сеанс) для хранения текущего сеанса в моей базе данных. Поэтому я просто взламываю user.token из запроса и использую его. Фу.. Часы работы.
1 ответ
Из документации видно, что вам нужно передать токен в Authorization
заголовок со значением: Bearer HEREISMYTOKEN
,
Подробнее о заголовке авторизации и заголовках здесь:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization
- https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Пример того, как его использовать, можно найти в этом ответе SO