Get oauth2.0 Access token with NodeJS - node.js

I'm having trouble getting an access token using node.
I can do it with Postman, but it expires when I restart my computer.
This is the code I made, reading some confusing documentation on the internet.
const axios = require('axios');
const config = {
url: 'https://aurl.com/connect/token',
method: 'get',
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
username: 'email#mail.com.br',
password: '1234',
scope: 'scope',
grant_type: 'password_credentials'
};
axios(config)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
I'm not an experienced programmer, I need help. ://

Related

Cookie token sent by server but not stored in browser

I have this code in node js API :
const jwt = require("jsonwebtoken");
generateToken = (user, res) => {
const token = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: "1800s",
});
res
.cookie("token", token, {
httpOnly: true,
})
.status(200)
.json({ message: "Logged in successfully 😊 👌" });
};
module.exports = generateToken;
I have this code in Next js project :
const onSubmitLogin = (data) => {
axios
.post(
`http://localhost:8000/login`,
{
email: data.email,
password: data.password,
},
{
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
}
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
If I use Postman, i get the cookie with the token.
But, when I use the browser I dont get the cookie stored in cookies.
I tried to add withCredentials: true, in axios request but nothing changes.
However, I get the message "Logged in successfully 😊 👌" in the browser's console

Nodejs- Unable to get access token from a 3rd party Auth Server using OAuth

This is my first attempt at connecting using a custom oAuth as i couldn't find a library for the particular service i am working with. Users from my app should be able to authenticate using another service provider like google/facebook. After going through the docs, i was able to mock up something like this to get the access token .
export async function getTokens({
code,
clientId,
clientSecret,
redirectUri,
}: {
code: string
clientId: string
clientSecret: string
redirectUri: string
}): Promise<{
access_token: string
expires_in: Number
refresh_token: string
scope: string
id_token: string
}> {
const url = "https://api.specificservice.dev/oauth/v1/token"
const values = {
code,
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUri,
grant_type: "authorization_code",
}
try {
const res = await axios.post(url, querystring.stringify(values), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
console.log(res.data)
return res.data
} catch (error: any) {
console.error(`Failed to fetch auth tokens`)
throw new Error(error.message)
}
}
After that i thought that i needed to provide a route that would allow a user initiate this flow.
app.get(`/${redirectURI}`, async (req, res) => {
const code = req.query.code as string
const { access_token } = await getTokens({
code,
clientId: CLIENT_ID,
clientSecret: CLIENT_SECRET,
redirectUri: `localhost:2000/${redirectURI}`,
})
// Fetch the user's profile with the access token and bearer
const epicUser = await axios
.get(
`https://authurlfromspecificservice`,
{
headers: {
Authorization: `Bearer ${access_token}`,
},
}
)
.then((res) => {
console.log(res.data)
return res.data
})
.catch((error) => {
console.error(`Failed to fetch user`)
throw new Error(error.message)
})
})
This did not work as expected because the access token wasn't returned. What do i do next?

Why do I get Error 401 trying to patch Auth0 app_metadata with the Management API?

I'm banging my head against the wall trying to solve issuing a patch request after getting an access token. This same access token works for get requests to https://${appDomain}/api/v2/users/${userid}. But it fails with "Request failed with status code 401" when trying to use it to patch app_metadata.
Using NodeJS and Axios.
axios
.post(`https://${appDomain}/oauth/token`, {
grant_type: 'client_credentials',
client_id: clientId,
client_secret: clientSecret,
audience: `https://${appDomain}/api/v2/`,
})
.then(({ data: { access_token, token_type } }) => {
const jwt = jwtDecode(access_token)
axios
.patch(`https://${appDomain}/api/v2/users/${userid}`, {
data: {
app_metadata: { stripeCustomerId: customer.id },
},
headers: {
Authorization: `${token_type} ${access_token}`,
},
})
.then(({ data }) => {
console.warn('patch response', data)
})
.catch((err) => {
console.error('patch error', err) // <--- ERROR 401 happens here
res.send(err)
})
})
.catch((err) => {
console.error('token error', err)
res.send(err)
})
After shadow boxing documentation I discovered a syntax error in my axios.patch call. Format should have been the following, which fixed my problems. I was passing data:{...} when it should have been like this:
axios.patch(
`https://${appDomain}/api/v2/users/${userid}`,
{
app_metadata: { stripeCustomerId: customer.id },
},
{
headers: {
Authorization: `${token_type} ${access_token}`,
},
}
)

Sending data from react server to node server

I am trying to send the data from input boxes in react server to nodejs server but everytime i am getting error on backend
TypeError: Cannot read property 'email' of undefined
Here is my code for that
onformsubmit=()=>{
console.log(this.state.email,this.state.password) ///gets printed correctly
axios.post('http://localhost:5000/acc-details',{
email:this.state.email,
password:this.state.password
})
.then(response=>{
console.log('success')
})
.catch(err=>console.log(err))
}
and then in node server
const express=require('express')
const app=express()
var bodyparser=require('body-parser')
app.use(bodyparser.json())
router.post('/acc-details',(req,res)=>{
console.log(req.body.email)
res.send('ok')
})
if not consoling in node server i am getting response back 'ok' as writtten above but i want to fetch my email and password on node server for db authentication
Modify your Axios request slightly to send multipart/form-data data.
onformsubmit = () => {
// Collect properties from the state
const {email, password} = this.state;
// Use FormData API
var formdata = new FormData();
formdata.append('email', email);
formdata.append('password', password);
axios.post('http://localhost:5000/acc-details', formdata)
.then( response=> {
console.log('success')
})
.catch(err=>console.log(err))
}
onformsubmit=()=>{
console.log(this.state.email,this.state.password) ///gets printed correctly
axios({
url: 'http://localhost:5000/acc-details'
method: 'POST',
data: { email: this.state.email, password: this.state.password }
})
.then(response=>{
console.log('success')
})
.catch(err=>console.log(err))
}
Now you should be able to access req.body
Edit:
after 200 tries, i figured out:
axios({
url: "http://localhost:5000/acc-details",
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
},
data: { email: this.state.email, password: this.state.password }
});```

23andMe API error: 'No grant_type provided.' 'invalid_request' OAuth2

I'm authenticating with the 23andMe API with OAuth 2. I'm able to receive the code after the user grants access. I'm currently trying to send a post request to receive the access token. I continue to receive this error:
data:
{ error_description: 'No grant_type provided.',
error: 'invalid_request' } }
I am using the axios package to make my post request. There is an error in my request because I got a successful 200 response and access token when I cuRL:
curl https://api.23andme.com/token/
-d client_id='zzz' \
-d client_secret='zzz' \
-d grant_type='authorization_code' \
-d code=zzz \
-d "redirect_uri=http://localhost:3000/receive_code/"
-d "scope=basic%20rszzz"
I'm able to receive the authorization code from the 23andMe server. I'm then redirected to my application. Here's my GET route:
router.get('/receive_code', function(req, res) {
axios.post('https://api.23andme.com/token/', {
client_id: zzz,
client_secret: zzz,
grant_type: 'authorization_code',
code: req.query.code,
redirect_uri: 'http://localhost:3000/receive_code/',
scope: "basic%20rs3094315"
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
});
Any thoughts?
The problem is the form key you've placed in your payload. It should work like this:
axios.post('https://api.23andme.com/token/', {
client_id: zzz,
client_secret: zzz,
grant_type: 'authorization_code',
code: req.query.code
redirect_uri: 'http://localhost:3000/receive_code/',
scope: "basic%20rs3094315"
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
I was able to solve the problem by using the simple-oauth2 npm package.
It can be found here: https://www.npmjs.com/package/simple-oauth2#express-and-github-example
// **********23ANDME OAUTH2************
var oauth2 = require('simple-oauth2')({
clientID: 'zzz',
clientSecret: 'zzz',
site: 'https://api.23andme.com',
tokenPath: '/token',
authorizationPath: '/authorize'
});
var authorization_uri = oauth2.authCode.authorizeURL({
redirect_uri: 'http://localhost:3000/receive_code/',
scope: 'basic analyses rs1234567',
state: 'jenvuece2a'
});
// *************************************
// In you view, place "/auth" in your <a> e.g. Click Me
router.get('/auth', function (req, res) {
res.redirect(authorization_uri);
});
router.get('/receive_code', function(req, res) {
var code = req.query.code;
if (!code) {
res.send('Error!!')
} else {
console.log('running');
oauth2.authCode.getToken({
code: code,
redirect_uri: 'http://localhost:3000/receive_code/'
}, saveToken);
function saveToken(error, result) {
if (error) {
console.log('Access Token Error', error.message);
} else {
token = oauth2.accessToken.create(result);
console.log(token);
}
};
res.render('/genetic_report', {layout: 'dash'});
}
});

Resources