How to hook up github oauth 2.0 with http in javascript - javascript

Good day,
I am trying on github oauth2.0 apis and got stuck on calling /access_token with fetch and axios.
I have successfully gotten /authorize api to work and have client_id, client_secret, and code passed successfully to getAccessToken function. However, failed at making the fetch with cors error issue returned.
Things that I had explored
https://www.sohamkamani.com/blog/javascript/2018-06-24-oauth-with-node-js/
https://github.com/sohamkamani/node-oauth-example
https://github.com/evert/fetch-mw-oauth2
Code:
export const authorize = async () => {
const uri = withQuery('https://github.com/login/oauth/authorize', {
client_id: process.env.VUE_APP_CLIENT_ID,
redirect_uri: 'http://localhost:8080/authorize',
scope: 'read:user',
});
window.location.replace(uri);
};
export const getAccessToken = async (code: string) => {
const { VUE_APP_CLIENT_ID, VUE_APP_CLIENT_SECRET } = process.env;
const uri = withQuery('https://github.com/login/oauth/access_token', {
client_id: VUE_APP_CLIENT_ID,
client_secret: VUE_APP_CLIENT_SECRET,
code,
});
axios({
method: 'post',
url: uri,
headers: {
accept: 'application/json',
},
}).then(response => {
console.log('response: ', response);
});
};
Axios error:
authorize:1 Access to XMLHttpRequest at 'https://github.com/login/oauth/access_token?client_id=abcdefgh&client_secret=abcdefgh' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
createError.js?2d83:16 Uncaught (in promise) Error: Network Error
at createError (createError.js?2d83:16)
at XMLHttpRequest.handleError (xhr.js?b50d:81)

Because of some security-related limitations, Github prevents developers from implementing the OAuth Web Application Flow on a client-side only application.
References:
https://github.com/isaacs/github/issues/330
Working Solution:
https://github.com/prose/gatekeeper

Related

OAuth2.0 token post request is responding 401 (invalid_client)

I am very new to the Google OAUth2.0 authentication and thus my question sounds like dumb. However, I am stuck with this problem quite a time and need your input to solve it.
I was integrating the Globus login within my app. Globus login using Google OAuth-2 protocol for authentication. According to the Globus Auth developer guide, I successfully redirect the app to their authorization service, the user can put their credential to authenticate, and the app receives the code returned from the Globus Auth server upon successful authentication. Next step is sending the code to the Token endpoint to get the access token. I used the following code:
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let tokenUri = encodeURIComponent(payload.redirect_uri);
let client_id = 'out app client id'
let client_secret = 'client secret generated for authentication'
let cred = btoa(client_secret);
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: tokenUri,
client_id: client_id
}),
{
headers:{
Authorization: 'Basic '+ cred,
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}
I am getting 401 {"error":"invalid_client"} code for this post request from the server. What am I missing?
N.B: I have tried without client secret, client id, not encoding redirect URL. No luck so far>
I would really appreciate your effort if you show me some light. Thanks for your time.
====Edited====
The error from the console at the browser is attached
I solved the problem. I had to put the client secret at the body of the post request. The following code resolves my problem.
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let client_id = 'app client id'
let client_secret = 'client secret generated for authentication'
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: payload.redirect_uri,
client_id: client_id,
client_secret: client_secret
}),
{
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}

Cannot get an accessToken from LinkedIn API due to 'redirect_uri' error

I am trying to achieve LinkedIn sign in using their API provided by Oauth2.0
According to docs - https://learn.microsoft.com/en-us/linkedin/shared/authentication/authorization-code-flow?context=linkedin/consumer/context
I am able to get access code (1 step). Afterwards I stuck on completing new request with error (to get an accessToken) - https://gyazo.com/abe24d7294aa4c1b9d8be9a101747ee2
Although I did configure my redirect URI in LinkedIn dev dashboard - https://gyazo.com/c533a589465042342d79438eab02d2a2
I've tried querystring.stringify method from query-string package
function trigerLogin() {
const accessToken = localStorage.getItem('AccessCode');
if (!accessToken) {
window.open('https://www.linkedin.com/uas/oauth2/authorization?response_type=code&state=DCEeFWf45A53sdfKef424&client_id=*************&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fcallback&scope=r_liteprofile+r_emailaddress', '_blank', 'top=100, left=200, height=500, width=500');
}
axios.post('https://www.linkedin.com/oauth/v2/accessToken', querystring.stringify({
client_id: '*************', // for safety reasons
grant_type: 'authorization_code',
code: accessToken,
redirect_uri: 'http://localhost:4000/callback',
client_secret: '**************' // for safety reasons
}))
.then(function (response) {
console.log(response);
})
.catch(error => {console.log(error)})
}
So I cannot get a response with a token with which I can work further
Thank you in advance!

Django Rest Framework CORS blocking XMLHttpRequest

I have set up my CORS policy using Django-cors-headers with the following settings:
APPEND_SLASH=False
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'localhost:8000',
'localhost:3000',
'localhost'
)
I have also added it to installed_apps and middleware.
Now I am making a React app for the front end and using AXIOS for my API requests. When I make an API request to log in to my app the CORS policy allows it. But, if I make an API request that requires a Token, I get:
Access to XMLHttpRequest at 'localhost:8000/api/TestConnection/' from origin 'http://localhost:3000' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
It seems that I need to allow XMLHttpRequest for supported protocol schemes but I cannot find anything in the pypi documentation about this.
EDIT:
Here is the AXIOS Request:
axios.post("localhost:8000/api/TestConnection/",
{headers:
{
'Authorization': "Bearer " + localStorage.getItem('JWTAccess')
}
},
{
testString: 'Hello API'
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
})
Thank you!
I Have had a similar issue with a ReactNative app which was happening due to ReactNative using IP 10.0.2.2 for localhost (I do not remember the details or why). I solved it by adding to my class.
componentWillMount() {
axios.defaults.baseURL = 'http://10.0.2.2:8000/api/';
axios.defaults.timeout = 1500;
}
I do not know if this is the right IP but may be worth looking at.
EDIT
handleRequest() {
const payload = { username: this.state.username, password: this.state.password }
axios
.post('login/', payload)
.then(response => {
const { token, user } = response.data;
// We set the returned token as the default authorization header
axios.defaults.headers.common.Authorization = `Token ${token}`;
// Navigate to the home screen
Actions.main();
})
.catch(error => {
console.log(error)
});
}
By saving the Token within my headers it is always sent.
The error says "from origin 'http://localhost:3000'" and to "check the cors policy"
I see your CORS policy is
CORS_ORIGIN_WHITELIST = (
'localhost:8000',
'localhost:3000',
'localhost'
)
maybe try providing the full http url. so
CORS_ORIGIN_WHITELIST = (
'localhost:8000',
'http://localhost:3000',
'localhost'
)
I solved it! The solution was very simple(of course),
For the request I needed to use part of #HenryM 's solution.
First I needed to establish the default url:
axios.defaults.baseURL = 'http://127.0.0.1:8000/api/';
Then I save the payload and header to const variables:
const header = {
headers:{
'Authorization': "Bearer " + localStorage.getItem('JWTAccess')
}
}
const payload = {
testValue: "Hello API"
}
Finally, the main issue was that my parameters were in the wrong order:
axios.post("TestConnection/", payload, header)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error);
Apparently the propper order, at least when using Django Rest Framework, is payload then header!!!
Thank you to everyone who tired to help!
This was the article that ended up helping me: https://www.techiediaries.com/django-vuejs-api-views/

CoinMarketCap API to Angular request

I have my head in water with the new CoinMarketCap API.
Below is an example of a request in Node. How can I make a request in Angular?
Any suggestions?
Thanks.
/* Example in Node.js ES6 using request-promise, concepts should translate
to your language of choice */
const rp = require('request-promise');
const requestOptions = {
method: 'GET',
uri: 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest',
qs: {
start: 1,
limit: 5000,
convert: 'USD'
},
headers: {
'X-CMC_PRO_API_KEY': 'API_KEY_HERE'
},
json: true,
gzip: true
};
rp(requestOptions).then(response => {
console.log('API call response:', response);
}).catch((err) => {
console.log('API call error:', err.message);
});
As per the documentation found here you cannot perform this HTTP call from a web client:
Making HTTP requests on the client side with Javascript is currently prohibited through CORS configuration. This is to protect your API Key which should not be visible to users of your application so your API Key is not stolen. Secure your API Key by routing calls through your own backend service.
A solution would be to create your own back-end API. This API can then perform the HTTP call to Coinmarketcap. Your website then communicates with your custom made back-end API.
getAllCoinsListing() {
const httpOptions = {
headers: new HttpHeaders({
'X-CMC_PRO_API_KEY': 'API_KEY_HERE'
})
};
return this.http.get(this.apiUrl, httpOptions);
}

ElectronJS Vue Axios Basic Authentication Access-Control-Allow-Origin error

I have been googling the all of the interwebs and I just can't find the solution to my problem. I'm trying to make an application using ElectronJS and I need to send an HTTP request with authentication basic header but I just can't get it to work.
Here's my code:
export default {
name: 'home',
data: function() {
return {token: ''}
},
methods: {
fetchData() {
this.$http({
method: 'get',
url: 'URL_TO_SERVER',
auth: {
username: 'USERNAME',
password: 'PASSWORD'
},
headers: {
'Access-Control-Allow-Origin': '*',
credentials: 'same-origin',
},
withCredentials: true,
}).then((response) => {
console.log(response.data);
}).catch((error) => {
console.log('ERROR: '+ error.response.data);
});
}
}
}
I am getting the following error:
XMLHttpRequest cannot load (URL_TO_SERVER). Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9080' is therefore not allowed access. The response had HTTP status code 401.
Does anyone have any idea's what could be my next step to fixing this?
If i do the same info with a REST client it will return the correct values, just not in ElectronJS
After building the application in to an EXE, it worked, just doesnt work in npm run dev.

Categories

Resources