你错过了
两者均已提取
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());
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);
const userName = user.name || 'Unknown User';
const userEmail = user.email || 'No email provided';
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:
结果