Closed IbrahimMoftah329 closed 2 weeks ago
Install Dependencies:
npm install express mongoose @clerk/clerk-sdk-node
Define a Mongoose model to store the Clerk user ID and any additional fields you want in your MongoDB database.
import mongoose, { Schema, Document } from 'mongoose';
interface IUser extends Document {
clerkUserId: string;
}
const UserSchema: Schema = new Schema({
clerkUserId: { type: String, required: true, unique: true },
});
const User = mongoose.model<IUser>('User', UserSchema);
export default User;
Create Express API Route to Save User ID: Next, create an Express route that will save the Clerk user ID into MongoDB. This route will be called from your React frontend after authentication.
import express from 'express';
import { getAuth } from '@clerk/clerk-sdk-node'; // Clerk's server-side SDK
import User from './models/User'; // Mongoose User model
const router = express.Router();
router.post('/api/save-user', async (req, res) => {
const { userId } = getAuth(req); // Get Clerk's userId from the authenticated request
try {
// Check if the user already exists in MongoDB
let user = await User.findOne({ clerkUserId: userId });
if (!user) {
// If the user doesn't exist, create a new record
user = new User({ clerkUserId: userId });
await user.save();
}
res.status(200).json({ message: 'User saved successfully', user });
} catch (error) {
res.status(500).json({ message: 'Error saving user', error });
}
});
export default router;
After authentication, Clerk provides a userId in the request. This ID is then saved in MongoDB if it’s not already present.
To ensure routes are protected, use Clerk middleware to require authentication.
import { requireAuth } from '@clerk/clerk-sdk-node'; // Clerk middleware
app.use(requireAuth());
Make sure you have the Clerk React SDK installed on the frontend.
npm install @clerk/clerk-react
Wrap the app with ClerkProvider to manage authentication.
import { ClerkProvider, RedirectToSignIn, SignedIn, SignedOut } from '@clerk/clerk-react';
const frontendApi = process.env.REACT_APP_CLERK_FRONTEND_API; // Clerk frontend API key
const App = () => (
<ClerkProvider frontendApi={frontendApi}>
<SignedIn>
{/* Protected routes/components */}
<YourMainApp />
</SignedIn>
<SignedOut>
<RedirectToSignIn />
</SignedOut>
</ClerkProvider>
);
export default App;
Once the user is authenticated on the frontend, you can retrieve their user ID using Clerk’s useUser hook, then send it to your Express backend.
import React, { useEffect } from 'react';
import { useUser } from '@clerk/clerk-react';
import axios from 'axios';
const Dashboard = () => {
const { user } = useUser();
useEffect(() => {
const saveUserToBackend = async () => {
if (user && user.id) {
try {
const response = await axios.post('/api/save-user', {}, {
headers: {
Authorization: `Bearer ${user.session.id}`, // Send the session token
},
});
console.log('User saved:', response.data);
} catch (error) {
console.error('Error saving user:', error);
}
}
};
saveUserToBackend();
}, [user]);
return <div>Welcome, {user?.fullName}!</div>;
};
export default Dashboard;
useUser() provides the authenticated user and their userId.
Once the user is authenticated, you can make a POST request to the backend route (/api/save-user), which saves the user ID to MongoDB.
Ensure that your MongoDB connection is established in your backend, usually in your server.js or app.js file.
import mongoose from 'mongoose';
const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
console.log('MongoDB Connected');
} catch (error) {
console.error('MongoDB connection error:', error);
process.exit(1);
}
};
connectDB();
https://dashboard.clerk.com/sign-in?redirect_url=https%3A%2F%2Fdashboard.clerk.com%2Fapps%2Fapp_2mQqzwzA1U3UMXVllJ689BMzbbo%2Finstances%2Fins_2mQqzxKUJo3RIYM1ynYytDPE4Ei
Using Clerk to handle all our User Authentication for us and use their preset templates to make things easier for us!
https://clerk.com/docs/components/overview
https://clerk.com/docs/quickstarts/react