Discord API - Not allowed to request source - javascript

I am trying to make „Login with Discord“ (OAuth) using Discords Api. I need the users ID, the Name and the role of the member in the guild.
It fails to fetch the source after I got redirected from the OAuth Page:
My JS for that page:
window.onload = () => {
const fragment = new URLSearchParams(window.location.hash.slice(1));
const [accessToken, tokenType] = [fragment.get('access_token'), fragment.get('token_type')];
fetch('http://discord.com/api/guilds/874613987487121408/members/491553591434412057', {
headers: {
authorization: `${tokenType} ${accessToken}`,
},
})
.then(result => result.json())
.then(response => {
const username = response.user;
const roles = response.roles;
document.getElementById('info').innerText += username + roles;
})
.catch(console.error);
};
However, it gets me an error message: Not allowed to request source.
Can someone help me?

Related

SharePoint cannot get Access Token with JavaScript?

I need to get access token from SharePoint, In order to upload some files!
I got access token from postman successfully, But when I try to do the same request with Javascript!
const generateToken = async () => {
const headers = { "Content-Type": "application/x-www-form-urlencoded" };
var formdata = {};
formdata["grant_type"] = "client_credentials";
formdata["client_id"] = "<client_id>";
formdata["client_secret"] = "<client_secret>";
formdata["resource"] =
"00000003-0000-0ff1-ce00-000000000000/site_url#tenant_id";
const body = Object.keys(formdata)
.map((key) => `${key}=${formdata[key]}`)
.join("&");
var requestOptions = {
method: "POST",
headers,
body,
};
await fetch(
"https://accounts.accesscontrol.windows.net/<tenant_id>/tokens/OAuth/2",
requestOptions
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));
};
generateToken();
when I execute the page which have this script I got this error
error TypeError: Failed to fetch
at generateToken
But IDK why the respose status is 200 OK, without returning body which contain access_token
Any help is much appreciated!
You cannot get the token from javascript like that, only from single page applications because of the security issues: you expose your client secret.
You can use Microsoft Authentication Library (MSAL) for JS instead.

Spotify API Fetch 401 and 400 error only valid bearer authentication supported

Under guidance of the Spotify WebAPI doc I am trying to get request user/account data via Client Credentials method. Spotify Doc. I am using a nested fetch request. I am getting a 400 and 401 response on my second fetch complaining about either not being authorized or
"message": "Only valid bearer authentication supported"
depending on my get request. I followed the doc and I have my token response that seems valid I'm unsure as to why it wouldn't be. Yes I tried different endpoints, and I reset my client secret. I have also included the code, the key was reset before posting so, code
import React, { Component, useState, useEffect } from 'react';
//Custom IMPORTS:
import '../PageCss/HeaderSection.css'
const Spotify = () => {
const [baseUrl, setBaseUrl] = useState("https://accounts.spotify.com/api/token");
const [spotifyArtists, setSpotifyArtists] = useState("https://api.spotify.com/v1/artist/7bSpQNOg9UsW530DuXM3X5");
const [token, setToken] = useState([]);
const [spotifyResonse, setspotifyResonse] = useState([]);
const [currentStatus, setStatus] = useState(false);
const [currentStatus2, setStatus2] = useState(false);
const client_id = '';
const client_secret = '48bdac084... f8ddb412';
useEffect(() => {
fetch(baseUrl,
{
method: 'POST',
body: 'grant_type=client_credentials&client_id=' + client_id + '&client_secret=' + client_secret,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then((response) => {
if (!response.ok) {
return Promise.reject(new Error("Spotify Token Request Error"));
}
else {
return response.json();
}
})
.catch((err) => {
console.log("First Fetch " + err);
})
.then((json) => {
try {
console.log("Current token after first fetch: " + json.access_token);
console.log(": " + json.token_type);
console.log(": " + json.expires_in);
setToken(json.access_token);
setStatus(true);
console.log("Fetch 2 Requesting data with token: " + token);
return fetch(spotifyArtists,{
method: 'GET',
headers: {
'Authorization': `Bearer ${token}` ,
'Content-Type': 'application/json'
}})
}
catch
{
return Promise.reject(new Error(`State Error!: Data: ${token} , Connection:${currentStatus}`));
}
})
.then((response) => {
if (!response.ok) {
return Promise.reject(new Error("Spotify Data Request with token Error" + response.status));
}
else {
return response.json();
}
})
.catch((err) => {
console.log("Second Fetch" + err);
})
.then((json) => {
try {
console.log("After data request: " + json)
console.log("Token after request" + token);
setspotifyResonse(json);
setStatus2(true);
}
catch
{
return Promise.reject(new Error(`State Error2 !: Data: ${spotifyResonse} , Connection2:${currentStatus2}`));
}
})
.catch((err) => {
console.log("After 2nd Fetch Error" + err);
})
}, [baseUrl, spotifyArtists]);
return (
<div >
</div>
)
};
export default Spotify;
Endpoints in question
Error Log
My request header yes the keys are different from above code, I had to redo this so many times.
Exact response
Welp, turns out after the help from discord that the spotify API and web have different artist URLS. A tiny letter 's' was the issue. GET /v1/artists/id HTTP/1.1. GET ARTISTS not ARTIST. Everything is working now r.i.p my free time.

Making my own API, confused on how to authenticate with server

I'm trying to make a Discord bot that retrieves a player's stats from the Ubisoft Rainbow Six stat website. I've worked with APIs before and I know the basics of Node and making GET requests to certain URLs. I monitored the network activity for a player's profile and found the specific URL that I need to perform a request on but I get a HTTP 400 error. I'm assuming this is because I've never authenticated with the server who I am. So I read up on authentication and the like and figured that all I had to do was include in the request header my username and password for the website(at this point I should mention that the site makes you login to retrieve player's stats). I went on Postman and included my username/password for Basic Auth and OAuth2 and I still get a HTTP 400 error, so there's obviously got to be more that I'm missing. It seems that in the network activity that some of the requests include a token, which I'm assuming is some sort of session token. I'm just completely confused as to what I'm supposed to do, as I'm kind of diving head first into this but I would really appreciate it if someone could provide some resources where I could try to fill in the gaps or help me resolve the issue. Code at the moment using pure JS/Node:
//import
const https = require('https');
const http = require('http');
//https://public-ubiservices.ubi.com/v3/profiles?namesOnPlatform=pope&platformType=uplay
var username = '';
var password = '';
var req_username = '';
//get session_id
function get_session_id(username, password) {
const options = {
host: 'public-ubiservices.ubi.com',
port: 443,
path: '/v3/profiles/sessions',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic' + Buffer.from(username + ':' + password).toString('base64'),
'Ubi-AppId': '',
}
}
const req_session_id = https.request(options, res => {
let res_body = '';
res.on('data', data => {
res_body += data;
})
res.on('end', () => {
res_body = JSON.parse(res_body);
console.log(res_body);
})
});
req_session_id.end();
}
//retrieve player stats
function get_stats(req_username) {
const options = {
host: 'public-ubiservices.ubi.com',
port: 443,
path: `/v3/profiles?namesOnPlatform=${req_username}&platformType=uplay`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Basic' + Buffer.from(username + ':' + password).toString('base64'),
'Ubi-AppId': '',
}
}
const req_get_stats = https.request(options, res => {
let res_body = '';
res.on('data', data => {
res_body += data;
});
res.on('end', () => {
res_body = JSON.parse(res_body);
console.log(res_body);
});
});
req_get_stats.end();
}
get_session_id(username, password);
get_stats(req_username);
try this out:
https://www.npmjs.com/package/r6api.js
heres an example:
const R6API = require('r6api.js');
const r6api = new R6API('email', 'password');
const username = 'Daniel.Nt'
const platform = 'uplay';
const id = await r6api.getId(platform, username).then(el => el[0].userId);
const stats = await r6api.getStats(platform, id).then(el => el[0]);
console.log(`${username} has played ${stats.pvp.general.matches} matches.`);

Difference between Python requests POST and axios POST

I am having a difficult time understanding why my API call does not work in axios (relatively new to JS). I have built an API server that takes in an Authorization header with a JWT token.
Here is my POST request workflow in Python:
resp = requests.post('http://127.0.0.1:8000/api/v1/login/access-token', data={'username': 'admin#xyz.com', 'password': 'password'})
token = resp.json()['access_token']
test = requests.post('http://127.0.0.1:8000/api/v1/login/test-token', headers={'Authorization': f'Bearer {token}'})
# ALL SUCCESSFUL
Using axios:
const handleLogin = () => {
const params = new URLSearchParams();
params.append('username', username.value);
params.append('password', password.value);
setError(null);
setLoading(true);
axios.post('http://localhost:8000/api/v1/login/access-token', params).then(response => {
console.log(response)
setLoading(false);
setUserSession(response.data.access_token);
props.history.push('/dashboard');
}).catch(error => {
setLoading(false);
console.log(error.response)
if (error.response.status === 401) {
setError(error.response.data.message);
} else {
setError("Something went wrong. Please try again later.");
}
});
}
// the above works fine
// however:
const [authLoading, setAuthLoading] = useState(true);
useEffect(() => {
const token = getToken();
if (!token) {
return;
}
axios.post(`http://localhost:8000/api/v1/login/test-token`, {
headers: {
'Authorization': 'Bearer ' + token
}
}).then(response => {
// setUserSession(response.data.token);
console.log('we made it')
setAuthLoading(false);
}).catch(error => {
removeUserSession();
setAuthLoading(false);
});
}, []);
if (authLoading && getToken()) {
return <div className="content">Checking Authentication...</div>
}
// RETURNS A 401 Unauthorized response...
What is different about the two above requests? Why does the axios version return different results than requests?
In my API, CORS have been set to *, and I know that the token within Axios is being saved properly in sessionStorage.
Any ideas?
As far as I can see you are passing your username and password in axios as params and as body data in your python request, I am not sure if your backend expects it as params or body data but try changing const params = new URLSearchParams(); to
const params = new FormData(); if the problem is that the backend isn't getting the body data it needs. The best thing I could recommend is checking your browser network tab and seeing what exactly the problem is when you hit your server.

How to access Express HTTP Request from Apollo Link Context, in a NextJS App?

I'm building a NextJS app, and I'm trying the access a cookie so I can use it to set a Http Header for GraphQL Request, I am using apollo-link-context. This is the code to create the ApolloClient
function createApolloClient(initialState = {}) {
const httpLink = new HttpLink({ uri: `${baseUrl}/graphql`, credentials: 'same-origin', fetch })
const authLink = setContext((_, prevCtx) => {
let token = ''
if (typeof window === 'undefined') token = getCookieFromServer(authCookieName, REQ)
else token = getCookieFromBrowser(authCookieName)
return ({ headers: { 'Auth-Token': token } })
})
const client = new ApolloClient({
ssrMode: typeof window === 'undefined',
cache: new InMemoryCache().restore(initialState),
link: authLink.concat(httpLink)
})
return client
}
The issue here is that the getCookieFromServer function expects an Express Request as the second argument, so it can extract the cookie from req.headers.cookie, and I have no idea where I can get it from there.
I finally found a way. Whenever I send a request from the server (in PageComponent.getInitialProps), I set the header in the context, then I can access it from setContext:
PageComponent.getInitialProps = async (ctx) => {
...
const token = getCookieFromServer(authCookieName, ctx.req)
const { data } = await client.query({
query,
context: { headers: { 'Auth-Token': token } }
})
...
}
Then in setContext:
const authLink = setContext((_, prevCtx) => {
let headers = prevCtx.headers || {}
if (!headers['Auth-Token']) {
const token = getCookieFromBrowser(authCookieName)
headers = { ...headers, 'Auth-Token': token }
}
return ({ headers })
})
So if the header is already present in the previous context (which is the case when sent from the server), just use it. If it is not present (when sent from the browser), get the cookie from the browser and set it.
I hope it will help somebody one day.

Categories