无法使用access_token从auth0获取用户信息

问题描述 投票:0回答:1

我正在尝试构建一个简单的身份验证库,并且我使用 axios 而不是 auth0 构建的库。我无法使用访问代码获取用户数据。我还使用谷歌提供商进行身份验证。

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
        }
    }
}


我正在快速应用程序中使用这个库来测试它。

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')
})

任何人都可以帮助我为什么我无法获取用户数据吗?我可以在我的 auth0 仪表板中看到用户数据 enter image description here

javascript node.js axios oauth auth0
1个回答
0
投票

你错过了

user.name
对象中提取了
user.email
user

您的程序在登录过程后获取用户信息(包括他们的姓名和电子邮件)的功能是正确的。

.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

结果

enter image description here

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.