我正在尝试构建一个简单的身份验证库,并且我使用 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')
})
你错过了
从
对象中提取了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