I am trying to build a simple authentication library, and I am using axios instead of library built by auth0. I am unable to fetch the userdata using the access code. I am also using google provider for authentication.
import axios from 'axios'
export default class Auth {
constructor(
private domain: string,
private client_id: string,
private redirect_uri: string
) {}
startAuthFlow(): string {
const params = new URLSearchParams({
response_type: 'code',
client_id: this.client_id,
redirect_uri: this.redirect_uri,
scope: 'offline_access'
})
const authURI = `https://${this.domain}/authorize?${params.toString()}`
return authURI
}
async handleCallback(code: string) {
return await this.exchangeCodeForToken(code)
}
async getUserInfo(accessToken: string) {
const userInfoEndpoint = `https://${this.domain}/userinfo`
try {
const response = await axios.get(userInfoEndpoint, {
params: {
scope: "openid profile email"
},
headers: {
Authorization: `Bearer ${accessToken}`
}
})
return response.data
} catch (error) {
throw error
}
}
async refreshToken(refresh_token: string) {
const tokenEndpoint = `https://${this.domain}/oauth/token`
const payload = {
grant_type: 'refresh_token',
client_id: this.client_id,
refresh_token
}
try {
const response = await axios.post(tokenEndpoint, payload, {
headers: {
'Content-Type': 'application/json'
}
})
return response.data
} catch (error) {
throw error
}
}
private async exchangeCodeForToken(code: string) {
const tokenEndPoint = `https://${this.domain}/oauth/token`
const payload = {
grant_type: 'authorization_code',
client_id: this.client_id,
client_secret: '[my client secret]',
code,
redirect_uri: this.redirect_uri,
scope: 'openid profile email'
}
try {
const reponse = await axios.post(tokenEndPoint, payload)
const { access_token, id_token, refresh_token } = reponse.data
return { access_token, id_token, refresh_token }
} catch (error) {
throw error
}
}
}
I am using this library in a express application to test it.
const express = require('express')
const Auth = require('../auth').default
const auth = new Auth('[domain].us.auth0.com', '[client ID]', 'http://localhost:3000/callback')
const app = new express()
app.get('/', (req,res) => {
return res.send('Hello')
})
app.get('/login', (req, res) => {
res.redirect(auth.startAuthFlow())
})
app.get('/callback', async (req, res) => {
const { code } = req.query
try {
const { access_token } = await auth.handleCallback(code)
console.log(access_token)
const user = await auth.getUserInfo(access_token)
console.log("USER: ", user)
res.redirect('/')
} catch (error) {
console.log(error)
return res.status(404).send(error)
}
})
app.listen(3000, () => {
console.log('Server running on port 3000')
})
Can anyone help me why I am not able to fetch the user data? I can see the userdata in my auth0 dashboard
You missed
Extracted both
user.name
anduser.email
from theuser
object
Your program is functionally correct in fetching the user's information (including their name and email) after the login process.
.env
AUTH0_DOMAIN=[your-domain].us.auth0.com
AUTH0_CLIENT_ID=[Your CLIENT ID]
AUTH0_CLIENT_SECRET=[Your CLIENT SECRET]
AUTH0_REDIRECT_URI=http://localhost:3000/callback
PORT=3000
tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
package.json
{
"dependencies": {
"axios": "^1.7.9",
"dotenv": "^16.4.7",
"express": "^4.21.2"
},
"devDependencies": {
"typescript": "^5.7.2"
}
}
clinet.ts
import axios from 'axios'
export default class Auth {
constructor(
private domain: string,
private client_id: string,
private redirect_uri: string,
private client_secret: string
) {}
startAuthFlow(): string {
const params = new URLSearchParams({
response_type: 'code',
client_id: this.client_id,
redirect_uri: this.redirect_uri,
scope: 'openid profile email offline_access'
});
const authURI = `https://${this.domain}/authorize?${params.toString()}`;
return authURI;
}
async handleCallback(code: string) {
return await this.exchangeCodeForToken(code);
}
async getUserInfo(accessToken: string) {
const userInfoEndpoint = `https://${this.domain}/userinfo`;
try {
const response = await axios.get(userInfoEndpoint, {
headers: {
Authorization: `Bearer ${accessToken}`
}
});
return response.data;
} catch (error) {
throw new Error(`Failed to fetch user info: ${error}`);
}
}
async refreshToken(refresh_token: string) {
const tokenEndpoint = `https://${this.domain}/oauth/token`;
const payload = {
grant_type: 'refresh_token',
client_id: this.client_id,
refresh_token
};
try {
const response = await axios.post(tokenEndpoint, payload, {
headers: {
'Content-Type': 'application/json'
}
});
return response.data;
} catch (error) {
throw new Error(`Failed to refresh token: ${error}`);
}
}
private async exchangeCodeForToken(code: string) {
const tokenEndPoint = `https://${this.domain}/oauth/token`;
const payload = {
grant_type: 'authorization_code',
client_id: this.client_id,
client_secret: this.client_secret,
code,
redirect_uri: this.redirect_uri
};
try {
const response = await axios.post(tokenEndPoint, payload, {
headers: {
'Content-Type': 'application/json'
}
});
const { access_token, id_token, refresh_token } = response.data;
return { access_token, id_token, refresh_token };
} catch (error) {
throw new Error(`Failed to exchange code for token: ${error}`);
}
}
}
server.js
require('dotenv').config();
const express = require('express');
const Auth = require('./client').default;
const auth = new Auth(
process.env.AUTH0_DOMAIN,
process.env.AUTH0_CLIENT_ID,
process.env.AUTH0_REDIRECT_URI,
process.env.AUTH0_CLIENT_SECRET
);
const app = express();
app.use(express.json());
// CORS Middleware (optional, for frontend integration)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
app.get('/', (req, res) => {
return res.send('Hello, Auth0 Demo!');
});
app.get('/login', (req, res) => {
res.redirect(auth.startAuthFlow());
});
app.get('/callback', async (req, res) => {
const { code } = req.query;
try {
const { access_token } = await auth.handleCallback(code);
const user = await auth.getUserInfo(access_token);
console.log('User Info:', user);
// Extract the user's name and email
const userName = user.name || 'Unknown User';
const userEmail = user.email || 'No email provided';
// Send the response with user details
res.send(`
<h1>Welcome, ${userName}!</h1>
<p>Email: ${userEmail}</p>
<p>User information has been logged to the console.</p>
`);
} catch (error) {
console.error(error);
res.status(500).send('Authentication failed');
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
npm install
client.ts
tsc
server.js
node server.js
http://localhost:3000/login