My knowledge of security is outdated and I am looking to update my skills in full stack development. Currently, I am exploring Oauth2, JWT, Next.JS, Auth0, and more, but I am struggling to integrate all these components together. Please bear with me as I make an effort to ask this question :)
Imagine I want to create a web application where users can register for access to a building. They would input their personal information and receive a user-friendly check-in number (e.g. A00001 - Z99999).
o/ ___
/▌ |App| --POST---> API --> Add User to MySQL, assign number-|
/\ ——— <---------------------Return number--------------------|
- How can I secure the
/user
POST endpoint to prevent spamming by malicious hackers?
Now, there is a security officer stationed at the entrance of the building with an admin app. They can view all users and approve their entry into the building.
O/ _________ ---PUT---> API --> Update User
/▌ |Admin App| ---GET---> API --> Retrieve All Users -|
/\ ————————— <-------send all users--------|
- How can I secure the
/user
GET endpoint so that only authenticated admins have access to view all users? - How can I secure the
/user
PUT endpoint so that only authenticated admins can modify user data? - The user should be able to log in but not register. There is only one admin account.
There is no registration process for the admin. Only one admin account with a username and password login.
Regular users do not require a GET /user/[id]
. However, is it secure if I send them a link with a 32-bit hash and then allow access through a GET /user/[hash]
endpoint?
For those willing to assist with code, I'll share a sample along with the question:
// pages/checkin.js
export default function Checkin() {
const checkin = async (e) => {
e.preventDefault();
try {
await fetch('https://myapi.com/user', {method: "POST", data});
} catch (err) {
console.log(err);
}
}
return (
<div>
<form onSubmit={checkin}>
{/* ... */}
</form>
</div>
)
}
// pages/_app.js
import { UserProvider } from "@auth0/nextjs-auth0";
function MyApp({ Component, pageProps }) {
return (
<UserProvider>
<Component {...pageProps} />
</UserProvider>
);
}
export default MyApp;
// pages/api/auth/[...auth0].js
import { handleAuth } from '@auth0/nextjs-auth0';
export default handleAuth();
// pages/userList.js
import { useUser } from '@auth0/nextjs-auth0';
export default function UserList() {
const { user, error, isLoading } = useUser();
if (isLoading) return <div>Loading...</div>;
if (error) return <div>{error.message}</div>;
{/*
* How and where do I fetch the secured users?
*/}
const ok = async (id) => {
try {
/*
* How to secure the PUT request?
*/
await fetch('https://myapi.com', {method: 'PUT', data: {id, ok: true}})
} catch (err) {
console.log(err);
}
}
return (
user && (
<div>
{users.map((user) => (
<div key={user.id}>
{user.human_numer} - <button onClick={() => ok(user.id)}>OK</button>
</div>
))}
</div>
)
);
}