Destiny 2 API recieving an auth token from endpoint using POST - javascript

Couple things to keep in mind, I'm a fairly beginner computer science student with a couple big projects under my belt. I mostly have been working with java so web is kinda new but seems easy enough to get used to.
I'm trying to send a post request to an endpoint that will return a membership id that I need.
I've been trying to follow along with these two documentation/guides:
https://github.com/Bungie-net/api/wiki/OAuth-Documentation
https://lowlidev.com.au/destiny/authentication-2#/tab-popup
On a side note, I really feel like there aren't many "get started" guides out there for working with the Bungie API but maybe that's intentional to prevent people from doing stupid stuff with people's accounts.
Anyways, I have successfully done the first part which is authorizing my app (registered on the bungie developers site) with the user's account using my client ID provided by Bungie. This returns a code inside the url that is your authorization code with the user's account. I have a kind of janky way of pulling it from the url, so any ideas of how I can improve it would be most appreciated.
document.getElementById("authButton").addEventListener("click", function(event) {
location.href = "https://www.bungie.net/en/OAuth/Authorize?client_id={my-client-id}&response_type=code&state=" + makeState(32);
});
var authCode = undefined;
if (window.location.href.includes("code=")) {
removeAuthButton();
authCode = window.location.href;
console.log(authCode);
var codeLoc = authCode.indexOf("code=");
var codeEndLoc = authCode.indexOf("&", 15);
authCode = authCode.substring(codeLoc + 5, codeEndLoc);
console.log(authCode);
}
This code is just executed after pressing a simple authorization button in the webpage, and bungie handles the redirect back to my page for me when I register my app.
Now after this, the documentation shows a POST request I need to make with the following:
POST https://www.bungie.net/platform/app/oauth/token/ HTTP/1.1
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
To stay with the urlencoded format, I have tried this code using an answer I found:
https://stackoverflow.com/a/53189376/16910197
document.getElementById("linkButton").addEventListener("click", function(event) {
fetch('https://www.bungie.net/Platform/App/OAuth/token/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
'client_id': "{my-client-id}",
'grant_type': "authorization_code",
'code': authCode
})
}).then(function(response) {
console.log(response);
return response.json();
});
});
This isn't working and I have modified it every way possible to try and get it to work to no avail. What am I missing?
Here is what I am getting back if needed:
Response { type: "cors", url: "https://www.bungie.net/Platform/App/OAuth/token/", redirected: false, status: 400, ok: false, statusText: "Bad Request", headers: Headers, body: ReadableStream, bodyUsed: false }
I'm a little new to stackoverflow and this is my first question, so let me know if I can format it any better.

You need to call toString on URLSearchParams and send the Authorization header. If you haven't already, you should switch your API key to use the "Confidential" OAuth Client Type
document.getElementById("linkButton").addEventListener("click", function(event) {
fetch('https://www.bungie.net/Platform/App/OAuth/token/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${window.btoa(`${bungie_client_id}:${bungie_client_secret}`)}`
},
body: new URLSearchParams({
'client_id': "{my-client-id}",
'grant_type': "authorization_code",
'code': authCode
}).toString()
}).then(function(response) {
console.log(response);
return response.json();
});
});
In case you didn't, check the network request in browser dev tools to see what JavaScript is actually POSTing to the endpoint.
From a fellow Destiny API dev, please capitalise "token" in the endpoint path before I lose my mind!

Related

Why does the server refuses to accept the request and throws 415 error?

I'm trying to build a sign up form and connect frontend with a backend server using fetch. But I've come across with a problem, that the server doesn't approve the connection and throw 415 error, IntelliJ IDEA shows this errow "Content type 'text/plain;charset=UTF-8' not supported".
"use strict";
/////////////////////////////////////////////////
// Data
let inputSignUpFirstName = document.querySelector(".signUp__input--firstName");
let inputSignUpLastName = document.querySelector(".signUp__input--lastName");
let inputSignUpPhoneNumber = document.querySelector(".signUp__input--phoneNumber");
let inputSignUpPin = document.querySelector(".signUp__input--pin");
const btnSignUp = document.querySelector(".signUp__btn");
const formSignUp = document.querySelector(".signUp");
/////////////////////////////////////////////////
// EventListeners
formSignUp.addEventListener("submit", addUser);
/////////////////////////////////////////////////
// Functions
function addUser(e){
e.preventDefault();
fetch("http://127.0.0.1:8080/registration", {
method: "POST",
headers: {
Accept: "application/json, text/plain;charset=UTF-8",
"Content-Type": "application/json",
},
mode: "no-cors",
body: JSON.stringify({
firstName: inputSignUpFirstName.value,
lastName: inputSignUpLastName.value,
telephoneNumber: inputSignUpPhoneNumber.value,
password: inputSignUpPin.value,
}),
})
.then((response) => {
console.log(response);
return response.json();
})
.then((data) => console.log(data))
.catch((error) => console.log(error));
}
We checked the url in Postman, and it works well. And one more strange thing, console.log(response) showed that my own url and the one i'm trying to send json to concatenate together like http://127.0.0.1:5501/127.0.0.1:8080/registration. Here is the result in the console:
Response {type: 'basic', url:
'http://127.0.0.1:5501/127.0.0.1:8080/registration', redirected:
false, status: 405, ok: false, …} body: (...) bodyUsed: true headers:
Headers {} ok: false redirected: false status: 405 statusText: "Method
Not Allowed" type: "basic" url:
"http://127.0.0.1:5501/127.0.0.1:8080/registration"
I'm doing this for the first time, so I might miss smth important. Thank you in advance for your advice.
UPDATE: I added "Access-Control-Allow-Origin": "http://127.0.0.1:5501" to the header, and the back-end added cors settings to IntelliJ IDEA. So we had to fix both front and the server. Thanks everyone for help!
For starters it could mean that the request method in your frontend and backend app are not the same, hence why you will get a status code of 405. Ensure that your request method which would be POST in this case is the same in both your frontend and backend app.
Error code of 415 will mean the response that is configured in the frontend app was not in the format that it was expecting from the backend. So you will need to either change the expected format in the frontend to match what is coming back from the backend or maybe you will need to convert the response coming from the backend to match back what is expected in the frontend.
I suspect the former, would be more appropriate given the source code that you have provided.

GitHub OAuth App - getting token

I have an simple web app I'm testing on localhost (using http-server) in which I'm trying to authorise it following the GitHub tutorial.
I was able to redirect to GitHub page so the user can login there and get the temporary code returned from GitHub as query parameter.
Yet I can't get auth token because every time I send a POST request with all the required data I'm getting CORB error.
The code I'm using to do that:
const getGitHubToken = async code => {
return await fetch(authData.accessTokenURL, {
method: 'POST',
body: {
client_id: authData.client_id,
client_secret: authData.client_secret,
code
},
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
};
So my questions are:
why isn't it working
is it safe to keep client_id and client_secret on client side
any suggestions if it's good idea to apply this approach when my aim is to create an app able to query GitHub API (general stats, public repos), how can I do it better?

How do I fetch cookie data with React?

I have a MERN + Passport.js application that is using fetch to make a call to my express API in order to retrieve data stored in a cookie. I have my React frontend routed to localhost:3000, and my backend routed to localhost:3001. My cookies are not being saved, and thus my session is not persisting within my browser. It is not an issue with the express-sessions or passport middleware, as when I use POSTMAN to execute the necessary calls to my API, the cookie is stored and the session persists.
It is only when I attempt to pass this information through/to my front end that things go wrong. I have been stumped for a while and can't seem to find an answer anywhere.
This is the line that I am using to save the cookie:
handleLogin(event) {
event.preventDefault();
fetch("http://localhost:3001/users/login", {
// credentials: 'include',
credentials: 'same-origin',
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
})
// .then( (response) => response.json())
.then( (response )=> {
if(response.message){
alert(response.message);
}
})
Which correctly calls my API, which logs the current session, user data, and cookie.
Upon refreshing and making another request, I lose the cookie (it was never properly stored in the first place I think), and all session data.
This is the get request that I make whenever I navigate to a new page:
componentDidMount(){
var current_user = "";
fetch("http://localhost:3001/users/", {
// credentials: 'include',
credentials: 'same-origin',
method: "get",
headers: {
'Accept':'application/json',
'Content-Type': 'application/json'
}
})
// .then( (response)=> response.json())
.then( (response)=> {
if(response.user){
current_user = response.user;
this.setState({
user: current_user
}), ()=> console.log(response);
}
})
}
In response, I get an undefined user and no other response, and the cookie is never stored in my browser. But again, if I do this in POSTMAN, strictly doing the POST request followed by that GET request, the proper user data is returned and the cookie is shown in POSTMAN as well.
Any idea as to why fetch is not passing the cookie information back to my front end? I have tried both credentials: 'include' and credentials: same-origin.
Thank you!
It seems like the problem, or at least part of it, is your use of same-origin. From Mozilla docs (italics my own):
omit: Never send cookies.
same-origin: Send user credentials (cookies, basic http auth, etc..) if the URL is on the same origin as the calling script. This is the default value.
include: Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls.
The definition of "same origin" does not include different ports.
If you change same-origin to include, fetch should start managing your cookies correctly.
If not - do you know for sure that the cookie is "never stored in the browser"? With Chrome, you can check chrome://settings/siteData.

How to pass api ID and api Key as authentication parameters of HTTP request

I am having trouble acessing the Oxford Dictionary API. I keep getting the error 'Authentication parameters missing'.
I believe I am not properly passing the api ID and key.
I have referred to this documentation:
https://developer.oxforddictionaries.com/documentation/making-requests-to-the-api
https://developer.oxforddictionaries.com/documentation
Here is my code; trust me that the app id and key are the correct strings.
const url = 'https://od-api.oxforddictionaries.com/api/v1/entries/en/swim';
fetch(url, {
method: 'GET',
headers: new Headers({
'app_id': oxford.appId, 'app_key': oxford.appKey
}),
}).then(function(response) {
console.log(response);
});
If the site looking for Authentication header it may refer to Basic Auth Header, read more here. If that is true, you simply can append your header parameter with this:
var headers = new Headers()
headers.append('Authorization', 'Basic ' + base64.encode(app_id + ":" + app_key));
You may try with or without the encoding.
You may also try this if that does not work
const url = 'https://od-api.oxforddictionaries.com/api/v1/entries/en/swim';
fetch(url, {
method: 'GET',
headers: { //HERE IS THE DIFFERENCE
'app_id': oxford.appId, 'app_key': oxford.appKey
},
mode: 'no-cors'
}).then(function(response) {
console.log(response);
});
If that does not work,
another way to think of, it may be a CORS issue, you can read it more here
May this helps.
I found an answer to my question here. Looks like the API does not support client side application requests. Guess I'll have to create a server.

LINE Login failed to get access token

I am trying to create a LINE login authentication function on my web. The problem I am encountering is that I kept receiving error 400, a bad request which may have something to do with the parameter I've put in.
Here is my code,
fetch('https://api.line.me/v2/oauth/accessToken', {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: JSON.stringify({
grant_type: 'authorization_code',
client_id: 'my_id',
client_secret: 'my_client_secret',
code: code,
redirect_uri: 'the link direct to'
})
}).then(response => {
console.log(response);
}).catch(function(err) {
console.log(err);
});
I followed the reference from LINE, https://developers.line.me/web-api/managing-access-tokens and put in the parameter it asked for, but I kept having the same error.
Tried with postman and got the same error
I am not sure which part I did wrong. Would someone help me with this issue?
I've got the same error 400 problem. In my case, my redirect_uri contains parameter e.g. mysite.com?action=abc which not work. It accept something like mysite.com/action/abc.
It seems no problem with your access token request.
Can you recheck the redirect_uri used by making an authorization request
is same to the callback URL registered in the LINE console?
As described in the Line Login documents:
redirect_uri : Callback URL. URL that users are redirected to after authentication and authorization. Must match one of the the callback URLs registered for your channel in the console.

Categories