Get config variables in auth0 in env file
This commit is contained in:
42
api/app.js
42
api/app.js
@@ -1,17 +1,10 @@
|
|||||||
const express = require("express");
|
const express = require("express");
|
||||||
const app = express();
|
const jwtAuthz = require("express-jwt-authz");
|
||||||
const passport = require("passport");
|
const asyncHandler = require("express-async-handler");
|
||||||
const { users } = require("./controllers");
|
const { users } = require("./controllers");
|
||||||
|
const secure = require("./middleware/secure");
|
||||||
|
|
||||||
/**
|
const app = express();
|
||||||
* Configure Passport
|
|
||||||
*/
|
|
||||||
|
|
||||||
try {
|
|
||||||
require("./config/passport")(passport);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure Express.js Middleware
|
* Configure Express.js Middleware
|
||||||
@@ -25,19 +18,9 @@ app.use(function (req, res, next) {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Initialize Passport and restore authentication state, if any, from the session
|
|
||||||
app.use(passport.initialize());
|
|
||||||
app.use(passport.session());
|
|
||||||
|
|
||||||
// Enable JSON use
|
// Enable JSON use
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
// Since Express doesn't support error handling of promises out of the box,
|
|
||||||
// this handler enables that
|
|
||||||
const asyncHandler = (fn) => (req, res, next) => {
|
|
||||||
return Promise.resolve(fn(req, res, next)).catch(next);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Routes - Public
|
* Routes - Public
|
||||||
*/
|
*/
|
||||||
@@ -46,10 +29,6 @@ app.options(`*`, (req, res) => {
|
|||||||
res.status(200).send();
|
res.status(200).send();
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post(`/users/register`, asyncHandler(users.register));
|
|
||||||
|
|
||||||
app.post(`/users/login`, asyncHandler(users.login));
|
|
||||||
|
|
||||||
app.get(`/test/`, (req, res) => {
|
app.get(`/test/`, (req, res) => {
|
||||||
res.status(200).send("Request received");
|
res.status(200).send("Request received");
|
||||||
});
|
});
|
||||||
@@ -58,10 +37,13 @@ app.get(`/test/`, (req, res) => {
|
|||||||
* Routes - Protected
|
* Routes - Protected
|
||||||
*/
|
*/
|
||||||
|
|
||||||
app.post(
|
app.get(
|
||||||
`/user`,
|
"/test-authorized/",
|
||||||
passport.authenticate("jwt", { session: false }),
|
secure,
|
||||||
asyncHandler(users.get)
|
jwtAuthz(["read:stuff"]),
|
||||||
|
function (req, res) {
|
||||||
|
res.send("Secured Resource");
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,7 +51,7 @@ app.post(
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
app.get(`/*`, (req, res) => {
|
app.get(`/*`, (req, res) => {
|
||||||
res.status(404).send("Route not found");
|
res.status(404).json({ error: "Not Found" });
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/**
|
|
||||||
* Config: Passport.js
|
|
||||||
*/
|
|
||||||
|
|
||||||
const StrategyJWT = require("passport-jwt").Strategy;
|
|
||||||
const ExtractJWT = require("passport-jwt").ExtractJwt;
|
|
||||||
|
|
||||||
const { users } = require("../models");
|
|
||||||
|
|
||||||
module.exports = (passport) => {
|
|
||||||
const options = {};
|
|
||||||
options.jwtFromRequest = ExtractJWT.fromAuthHeaderAsBearerToken();
|
|
||||||
options.secretOrKey = process.env.tokenSecret; // Change this to only use your own secret token
|
|
||||||
|
|
||||||
passport.use(
|
|
||||||
new StrategyJWT(options, async (jwtPayload, done) => {
|
|
||||||
let user;
|
|
||||||
try {
|
|
||||||
user = await users.getById(jwtPayload.id);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
return done(error, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return done(null, false);
|
|
||||||
}
|
|
||||||
return done(null, user);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
||||||
19
api/middleware/secure.js
Normal file
19
api/middleware/secure.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
const jwt = require("express-jwt");
|
||||||
|
const jwksRsa = require("jwks-rsa");
|
||||||
|
|
||||||
|
const secure = jwt({
|
||||||
|
// Dynamically provide a signing key based on the kid in the header and the signing keys provided by the JWKS endpoint
|
||||||
|
secret: jwksRsa.expressJwtSecret({
|
||||||
|
cache: true,
|
||||||
|
rateLimit: true,
|
||||||
|
jwksRequestsPerMinute: 5,
|
||||||
|
jwksUri: `https://${process.env.SNOWPACK_PUBLIC_AUTH0_DOMAIN}/.well-known/jwks.json`,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Validate the audience and the issuer
|
||||||
|
audience: `https://${process.env.SNOWPACK_PUBLIC_API_DOMAIN}/`, //replace with your API's audience, available at Dashboard > APIs
|
||||||
|
issuer: `https://${process.env.SNOWPACK_PUBLIC_AUTH0_DOMAIN}/`,
|
||||||
|
algorithms: ["RS256"],
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = secure;
|
||||||
@@ -5,9 +5,11 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"express-async-handler": "^1.1.4",
|
||||||
|
"express-jwt": "^6.1.0",
|
||||||
|
"express-jwt-authz": "^2.4.1",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"passport": "^0.4.1",
|
"jwks-rsa": "^2.0.4",
|
||||||
"passport-jwt": "^4.0.0",
|
|
||||||
"shortid": "^2.2.15"
|
"shortid": "^2.2.15"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
"preview": "astro preview"
|
"preview": "astro preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"astro": "^0.20.7",
|
"@astrojs/renderer-react": "^0.2.1",
|
||||||
"@astrojs/renderer-react": "^0.2.1"
|
"@snowpack/plugin-dotenv": "^2.2.0",
|
||||||
|
"astro": "^0.20.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@auth0/auth0-react": "^1.8.0"
|
"@auth0/auth0-react": "^1.8.0"
|
||||||
|
|||||||
3
site/snowpack.config.mjs
Normal file
3
site/snowpack.config.mjs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default {
|
||||||
|
plugins: [["@snowpack/plugin-dotenv", { dir: "../" }]],
|
||||||
|
};
|
||||||
@@ -4,14 +4,15 @@ import LoginButton from "./LoginButton";
|
|||||||
import LogoutButton from "./LogoutButton";
|
import LogoutButton from "./LogoutButton";
|
||||||
import Profile from "./Profile";
|
import Profile from "./Profile";
|
||||||
import ProfileFromApi from "./ProfileFromApi";
|
import ProfileFromApi from "./ProfileFromApi";
|
||||||
|
import config from "../config";
|
||||||
|
|
||||||
const AuthTest = () => {
|
const AuthTest = () => {
|
||||||
return (
|
return (
|
||||||
<Auth0Provider
|
<Auth0Provider
|
||||||
domain="dev-b-bgocbi.us.auth0.com"
|
domain={config.auth0.domain}
|
||||||
clientId="c5A08v815qx3ySjffHbaUc5b5MPWhRad"
|
clientId={config.auth0.clientId}
|
||||||
redirectUri={window.location.origin}
|
redirectUri={window.location.origin}
|
||||||
audience="https://1t8da6s66e.execute-api.us-east-1.amazonaws.com/"
|
audience={config.auth0.audience}
|
||||||
scope="read:stuff"
|
scope="read:stuff"
|
||||||
>
|
>
|
||||||
<LoginButton />
|
<LoginButton />
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ const ProfileFromApi = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getMessage = async () => {
|
const getMessage = async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const accessToken = await getAccessTokenSilently({
|
const accessToken = await getAccessTokenSilently({
|
||||||
audience: "https://1t8da6s66e.execute-api.us-east-1.amazonaws.com/",
|
audience: "https://1t8da6s66e.execute-api.us-east-1.amazonaws.com/",
|
||||||
scope: "read:stuff",
|
scope: "read:stuff",
|
||||||
});
|
});
|
||||||
|
|
||||||
const authorizedUrl = "https://1t8da6s66e.execute-api.us-east-1.amazonaws.com/authorized";
|
const authorizedUrl =
|
||||||
|
"https://1t8da6s66e.execute-api.us-east-1.amazonaws.com/authorized";
|
||||||
|
|
||||||
const authorizedResponse = await fetch(authorizedUrl, {
|
const authorizedResponse = await fetch(authorizedUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
@@ -40,11 +40,7 @@ const ProfileFromApi = () => {
|
|||||||
<h2>{user.name}</h2>
|
<h2>{user.name}</h2>
|
||||||
<p>{user.email}</p>
|
<p>{user.email}</p>
|
||||||
<h3>API Message</h3>
|
<h3>API Message</h3>
|
||||||
{message ? (
|
{message ? <pre>{message}</pre> : "No message found"}
|
||||||
<pre>{message}</pre>
|
|
||||||
) : (
|
|
||||||
"No message found"
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ config.domains = {};
|
|||||||
* This will enable your front-end to communicate with your back-end.
|
* This will enable your front-end to communicate with your back-end.
|
||||||
* (e.g. 'https://api.mydomain.com' or 'https://091jafsl10.execute-api.us-east-1.amazonaws.com')
|
* (e.g. 'https://api.mydomain.com' or 'https://091jafsl10.execute-api.us-east-1.amazonaws.com')
|
||||||
*/
|
*/
|
||||||
config.domains.api = "https://1t8da6s66e.execute-api.us-east-1.amazonaws.com";
|
config.domains.api = `https://${import.meta.env.SNOWPACK_PUBLIC_API_DOMAIN}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auth0 config values
|
||||||
|
*/
|
||||||
|
config.auth0 = {};
|
||||||
|
config.auth0.domain = import.meta.env.SNOWPACK_PUBLIC_AUTH0_DOMAIN;
|
||||||
|
config.auth0.clientId = import.meta.env.SNOWPACK_PUBLIC_AUTH0_CLIENT_ID;
|
||||||
|
config.auth0.audience = `https://${import.meta.env.SNOWPACK_PUBLIC_API_DOMAIN}/`;
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ let title = 'My Astro Site';
|
|||||||
|
|
||||||
// Full Astro Component Syntax:
|
// Full Astro Component Syntax:
|
||||||
// https://docs.astro.build/core-concepts/astro-components/
|
// https://docs.astro.build/core-concepts/astro-components/
|
||||||
|
|
||||||
---
|
---
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
|||||||
Reference in New Issue
Block a user