K
Kinde7mo ago
Kin

Server and Client side connection

Hello Kinde Team, I am wondering how I will go about implementing authentication for both client side and server side for full stack. My app is made using React as the frontend and Express as the backend. I successfully implemented the frontend auth using Kinde however I still need to authenticate api calls in the Express backend. I saw a little section about using the middleware but I couldn’t find the exact steps to implement this. I have written my process of authenticating, please let me know if this process is correct for Kinde’s use case.
39 Replies
Kin
Kin7mo ago
1. User Login on Client Side: The user enters their credentials (username and password) on the client-side application built with React. Using Kinde Auth for React SDK, you handle this login request. The SDK directly interacts with Kinde’s authentication API. 2. Token Handling: Upon successful authentication, Kinde’s API responds with an authentication token (JWT). This token is typically stored in the client’s local storage or in-memory storage, depending on your security requirements. Kinde handles the token management, which simplifies the process. 3. Token Verification for Protected Routes: When the client makes a request to a protected route on your backend (built with Node.js and Express.js, for instance), you need to send this token as part of the request headers. On the server side, you should have a middleware that verifies the token’s validity. This can be done using Kinde’s libraries or other JWT validation methods. 4. Backend Response: Once the token is verified and the request is authenticated, your backend performs the necessary action and sends the response back to the client. This could be data retrieval, modification, or any other server-side logic. 5. Client-Side Handling: The client-side application, upon receiving the response, will then proceed with the appropriate actions based on the server’s response. This could involve rendering user-specific data, redirecting to a different component, etc. This is my thought process if this is generally correct, I would like assistance on implementing the middleware to my express app.
Oli - Kinde
Oli - Kinde7mo ago
Hey @Kin, Thanks for reaching out and taking the time to explain your thinking towards using Kinde for your setup. Your process for implementing authentication with Kinde in a full-stack application using React for the frontend and Express.js for the backend is generally correct. Here's a breakdown of your steps with some additional insights and recommendations based on Kinde's documentation: 1. User Login on Client Side: Correct. Users will log in using the React frontend, and the Kinde Auth React SDK will handle the authentication with Kinde's API. Upon successful login, Kinde will issue an authentication token (JWT). 2. Token Handling: Correct. The received JWT should be securely stored on the client side, typically in local storage or session storage, though the choice depends on your application's security requirements. Kinde's SDKs facilitate token management. 3. Token Verification for Protected Routes: Correct. When accessing protected routes on your backend, the client must include the JWT in the request headers. On the server side, you should implement middleware that verifies the token's validity. According to Kinde's documentation, you can use the @kinde-oss/kinde-node package for Express.js applications to easily verify the token and protect your routes. 4. Backend Response: Correct. After the token verification, your backend will process the request and respond accordingly. This ensures that only authenticated requests are processed for protected routes. 5. Client-Side Handling: Correct. The client application handles the response from the backend, which may involve rendering data, navigating to different parts of the application, or handling errors. To implement the middleware in your Express app for token verification, you can follow these steps: 1. Install the @kinde-oss/kinde-node package in your Express app:
npm install @kinde-oss/kinde-node

npm install @kinde-oss/kinde-node

2. Import and initialize the Kinde middleware in your Express app. You'll need to provide your Kinde domain to fetch the verification keys for your app:
const express = require('express');
const { kindeNode } = require('@kinde-oss/kinde-node');
const app = express();

let authenticate;

(async () => {
authenticate = await kindeNode(YOUR_KINDE_DOMAIN);
})();
const express = require('express');
const { kindeNode } = require('@kinde-oss/kinde-node');
const app = express();

let authenticate;

(async () => {
authenticate = await kindeNode(YOUR_KINDE_DOMAIN);
})();
3. Protect your routes using the authenticate middleware:
app.get('/api/protected', authenticate, (req, res) => {
res.json({ message: 'This is a protected route' });
});
app.get('/api/protected', authenticate, (req, res) => {
res.json({ message: 'This is a protected route' });
});
Replace YOUR_KINDE_DOMAIN with your actual Kinde domain. This setup ensures that only requests with a valid JWT can access your protected routes. If you have any specific questions or need further assistance, feel free to ask!
Kin
Kin7mo ago
awesome thank you so much this is exactly what i needed. Just another clarifying question: will this require me to make a new app in my Kinde Account? @Oli - Kinde or does the package know my token since im providing my domain
Oli - Kinde
Oli - Kinde7mo ago
You would have to create 2 applications in Kinde, one for your React frontend app, and one for your Express backend
mohamed222
mohamed2227mo ago
Hi @Oli - Kinde Continuing on this. Im trying to implement this same pattern but with fastapi on my backend. Normally I would have the jwt secret and then decode the token that way, but the react app doesn't give me the secret to decode the token. Further creating a new app under the same project produces a secret that is invalid for decoding the jwt token sent by react. How would I go about doing this in python? Thanks in advance
Oli - Kinde
Oli - Kinde7mo ago
Hey @mohamed222, I can for sure help you out. To implement authentication in your FastAPI backend using Kinde, you don't need the JWT secret to decode the token. Instead, you should verify the JWT token using Kinde's public keys. This approach is more secure and aligns with best practices for handling JWTs. Here's a general process to authenticate API calls in your FastAPI backend: 1. Install Required Packages: Ensure you have fastapi, uvicorn, and kinde-python-sdk installed in your environment. If not, you can install them using pip:
pip install fastapi uvicorn kinde-python-sdk

pip install fastapi uvicorn kinde-python-sdk

2. Set Up FastAPI Application: Create your FastAPI application as usual. Define your routes and any business logic needed. 3. Authenticate Requests: For routes that require authentication, you'll need to verify the JWT token that comes from the client (React app). You can do this by extracting the token from the request headers and then using Kinde's SDK or a custom function to verify the token against Kinde's public keys. Here's a simplified example of how you might set up a route in FastAPI that requires authentication:
from fastapi import FastAPI, Depends, HTTPException
from kinde_sdk import KindeApiClient, Configuration, GrantType

app = FastAPI()

# Configure the Kinde API client
configuration = Configuration(host='https://<your_kinde_subdomain>.kinde.com')
kinde_client = KindeApiClient(
configuration=configuration,
domain='https://<your_kinde_subdomain>.kinde.com',
client_id="<CLIENT_ID>",
client_secret="<CLIENT_SECRET>",
grant_type=GrantType.CLIENT_CREDENTIALS
)

async def get_current_user(token: str = Depends(kinde_client.oauth2_scheme)):
try:
payload = kinde_client.decode_token(token)
return payload
except Exception as e:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")

@app.get("/protected")
async def protected_route(user: dict = Depends(get_current_user)):
return {"message": "This is a protected route", "user": user}
from fastapi import FastAPI, Depends, HTTPException
from kinde_sdk import KindeApiClient, Configuration, GrantType

app = FastAPI()

# Configure the Kinde API client
configuration = Configuration(host='https://<your_kinde_subdomain>.kinde.com')
kinde_client = KindeApiClient(
configuration=configuration,
domain='https://<your_kinde_subdomain>.kinde.com',
client_id="<CLIENT_ID>",
client_secret="<CLIENT_SECRET>",
grant_type=GrantType.CLIENT_CREDENTIALS
)

async def get_current_user(token: str = Depends(kinde_client.oauth2_scheme)):
try:
payload = kinde_client.decode_token(token)
return payload
except Exception as e:
raise HTTPException(status_code=401, detail="Invalid authentication credentials")

@app.get("/protected")
async def protected_route(user: dict = Depends(get_current_user)):
return {"message": "This is a protected route", "user": user}
In this example, replace <your_kinde_subdomain>, <CLIENT_ID>, and <CLIENT_SECRET> with your actual Kinde details. The get_current_user dependency extracts the token from the request, decodes it using Kinde's SDK, and verifies it. If the token is valid, the protected route will return a message along with the user details extracted from the token. This approach ensures that only requests with a valid JWT token can access your protected routes. For more detailed information and the latest updates on using Kinde with FastAPI, please refer to the Kinde Python SDK documentation. Let me know if you have any further questions.
mohamed222
mohamed2227mo ago
ok interesting will try this out and let you know! Thanks @Oli - Kinde
Kin
Kin7mo ago
Hello ive been trying this and its saying that: authenticate = await kindeNode('my_domain'); TypeError: kindeNode is not a function ive installed the package and the imported it and it still doesn seem to work
Oli - Kinde
Oli - Kinde7mo ago
Hi @Kin, I have reached out to a teammate to look into your issue further. Hey @Kin, Are you able to check you've got the kindeNode module export in your folders (.../node_modules/@kinde-oss/kinde-node/dist/cjs/index.js) - this would ensure that it was correctly installed - should look something like
'use strict';

const {getPem, authToken} = require('@kinde-oss/kinde-node-auth-utils').default;

const kindeNode = async (domain) => {
const pem = await getPem(domain);

return (req, callback) => {
const authHeader = req.headers.authorization;
// Remove 'Bearer ' prefix
const token = authHeader && authHeader.split(' ')[1];

return authToken(token, pem, (err, userString) => {
const user = err ? {} : JSON.parse(userString);
return callback(err, user);
});
};
};

module.exports = kindeNode;
'use strict';

const {getPem, authToken} = require('@kinde-oss/kinde-node-auth-utils').default;

const kindeNode = async (domain) => {
const pem = await getPem(domain);

return (req, callback) => {
const authHeader = req.headers.authorization;
// Remove 'Bearer ' prefix
const token = authHeader && authHeader.split(' ')[1];

return authToken(token, pem, (err, userString) => {
const user = err ? {} : JSON.parse(userString);
return callback(err, user);
});
};
};

module.exports = kindeNode;
Let me know.
Kin
Kin7mo ago
yep its there 🙂 should I reinstall my node modules? Could not find a declaration file for module '@kinde-oss/kinde-node'. '/Users/kawai/Documents/projects/Mangetsu/backend/node_modules/@kinde-oss/kinde-node/dist/cjs/index.js' implicitly has an 'any' type. Try npm i --save-dev @types/kinde-oss__kinde-node if it exists or add a new declaration (.d.ts) file containing declare module '@kinde-oss/kinde-node';ts(7016) its also showing this at the import
Kin
Kin7mo ago
No description
Oli - Kinde
Oli - Kinde7mo ago
Hey @Kin, It seems like you need to include declare module '@kinde-oss/kinde-node' in an your declaration .d.ts file. Let me know if this does not solve your issue.
Kin
Kin7mo ago
To use this package do i need to have typescript? My app is a full javascript app It seems like this issue isnt getting solved even if I do this
Oli - Kinde
Oli - Kinde7mo ago
Okay I will get one of my TypeScipt/Node expert teammates to look into this and get back to you.
Kin
Kin7mo ago
I just dont understand how kinde auth works on express like if my backend runs on port 4000 and my frontend runs on port 3000 and both ports have their own kinde config since its two different apps how are they meant to communicate with eachother?
Want results from more Discord servers?
Add your server