我有一个带有 Node.js 服务器的 React 应用程序。
目录结构如下:
.env
应用程序
.env
.gitignore
build/
node_modules/
package copy.jsonpackage
-
lock.jsonpackage.jsonpublic
/
README.md
服务器
.env
node_modules
包-lock.json
包.json
server.js
src
App.css
App.js
Cognito.js
Page.js
Login.js
您会注意到 .env 位于多个位置。以下是我对其可能位置的猜测。也许它不应该位于这些位置中的任何一个。
该应用程序将被构建并上传到 AWS Amplify 可以访问的私有 GitHub 存储库。然后,AWS Amplify 从存储库获取文件并允许网站运行。
以下是 server.js 的一部分:
const express = require('express');
const axios = require('axios');
const cors = require('cors');
const jwt = require('jsonwebtoken');
const jwkToPem = require('jwk-to-pem');
const dotenv = require('dotenv');
const app = express();
const port = 4000;
dotenv.config(); // Load environment variables from .env file
const CLIENT_ID = process.env.REACT_APP_CLIENT_ID;
const CLIENT_SECRET = process.env.REACT_APP_CLIENT_SECRET;
[...]
const base64Credentials = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64');
app.use(cors());
app.use(express.json());
app.get('/', (req, res) => {
res.send('Server is running!');
});
// Route to verify Cognito token
app.post('/verifyToken', async (req, res) => {
const token = req.body.token;
try {
const jwks = await axios.get('https://cognito-idp.us-[region].amazonaws.com/[region and pool ID]/.well-known/jwks.json');
const pem = jwkToPem(jwks.data.keys[0]);
jwt.verify(token, pem, { algorithms: ['RS256'] }, (err, decodedToken) => {
[...]
app.post('/exchangeCode', async (req, res) => {
const { code } = req.body;
[...]
try {
const params = new URLSearchParams();
params.append('code', code);
params.append('grant_type', 'authorization_code');
params.append('redirect_uri', 'http://localhost:3000/dashboard');
const response = await axios.post('https://auth.[real domain].com/oauth2/token', params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Basic ${base64Credentials}`
}
});
// Log the response data for debugging
console.log('Token Exchange Response:', response.data);
res.json(response.data);
} [...]
Cognito.js 的一部分:
import React, { createContext, useContext, useState, useEffect } from 'react';
import { CognitoUser, AuthenticationDetails, CognitoUserPool } from 'amazon-cognito-identity-js';
// Initialize Cognito User Pool with environment variables
const USER_POOL_ID = process.env.REACT_APP_USER_POOL_ID;
const CLIENT_ID = process.env.REACT_APP_CLIENT_ID;
const userPool = new CognitoUserPool({
UserPoolId: USER_POOL_ID,
ClientId: CLIENT_ID
});
const CognitoContext = createContext();
const exchangeCodeForTokens = async (code) => {
try {
const response = await fetch('http://localhost:4000/exchangeCode', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ code })
});
[...]
export const CognitoProvider = ({ children }) => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [email, setEmail] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
exchangeCodeForTokens(code).then(email => {
setIsLoggedIn(true);
setEmail(email);
}).catch(err => {
setError(err.message);
});
}
}, []);
const handleLogin = () => {
const user = new CognitoUser({ Username: username, Pool: userPool });
const authenticationDetails = new AuthenticationDetails({ Username: username, Password: password });
user.authenticateUser(authenticationDetails, {
onSuccess: (session) => {
setIsLoggedIn(true);
// Fetch email attribute after successful login
user.getUserAttributes((err, attributes) => {
[...]
我在想:
- AWS Amplify 允许您通过 Amplify 控制台设置环境变量,因此即使 repo 是私有的,也不应将 .env 上传到 GitHub。
- .env 的内容在目录之间可能不一样。