Authenticating API calls with Kinde
I have a react native app and a backend NextJS app both running Kinde.
How to authenticate API calls from the app to the backend to authenticate a user?
Authorization: Bearer {token}
in http headers doesn't work with idToken or accessToken28 Replies
i registered the API as described here https://docs.kinde.com/developer-tools/your-apis/register-manage-apis/
I am using the
expo-startkit
and I am not sure where to pass the audience
parameter. exchangeCodeAsync
, request.promptAsync
and authRequest
do not accept that parameterKinde docs
Register and manage APIs
Our developer tools provide everything you need to get started with Kinde.
Hi @Tito ,
Thank you for reaching out. To ensure that your API calls are authenticated correctly, it's essential to include the appropriate audience parameter when initializing the Kinde SDK in your React Native application. This audience parameter specifies the intended recipient of the token, typically your backend API.
In your React Native application, when setting up the Kinde SDK, include the audience parameter in the configuration.
Here's an example of how to do this:
import { KindeSDK } from '@kinde-oss/react-native-sdk-0-7x'; const client = new KindeSDK( 'YOUR_KINDE_DOMAIN', 'YOUR_REDIRECT_URI', 'YOUR_CLIENT_ID', 'YOUR_POST_LOGOUT_REDIRECT_URI', 'profile email openid', { audience: 'https://yourapi.example.com', } ); export default client;Ensure that the audience value matches the Audience URL you specified when registering your API in the Kinde dashboard. https://docs.kinde.com/developer-tools/sdks/native/expo-react-native After initializing the SDK and obtaining the access token, include it in the Authorization header of your HTTP requests from the React Native app to your Next.js backend. Example:
const response = await fetch('https://yourapi.example.com/endpoint', {
method: 'GET',
headers: {
Authorization: Bearer ${accessToken}
,
},
});
On your Next.js backend, validate the incoming token to ensure it's valid and has the correct audience claim.
Additional Considerations:
- Ensure that you're using a compatible version of the Kinde React Native SDK with your Expo setup.
https://docs.kinde.com/developer-tools/sdks/native/react-native-sdk
Token Validation: On your backend, verify the access token's aud claim to ensure it matches your API's audience identifier. This step is crucial for security to confirm that the token was intended for your API.
If you encounter further issues or have additional questions, please don't hesitate to reach outKinde docs
Expo and React Native SDK
Our developer tools provide everything you need to get started with Kinde.
Kinde docs
React Native SDK
Our developer tools provide everything you need to get started with Kinde.
I wasn't able to use
@kinde-oss/react-native-sdk-0-7x
(doesn't use expo-storage
properly) nor @kinde/expo
(doesn't work, probably because it doesn't redirect back to app correctly), so I had to use
https://github.com/kinde-starter-kits/expo-starter-kit/ directly. Where should I pass the audience
parameter there?GitHub
GitHub - kinde-starter-kits/expo-starter-kit
Contribute to kinde-starter-kits/expo-starter-kit development by creating an account on GitHub.
Hi Tito,
Hope you're doing well! 😊
To pass the audience parameter in your Expo Starter Kit setup, you’ll need to update the authentication request inside
Find this section in your
Make sure to replace
This ensures your tokens are issued for the correct API. Let me know if you have any questions—happy to help! 🚀
Hope you're doing well! 😊
To pass the audience parameter in your Expo Starter Kit setup, you’ll need to update the authentication request inside
app/index.tsx
.Find this section in your
authenticate
function and modify it like this:
const request = new AuthRequest({
clientId: process.env.EXPO_PUBLIC_KINDE_CLIENT_ID!,
redirectUri,
scopes: ['openid', 'profile', 'email', 'offline'],
responseType: "code",
extraParams: {
has_success_page: "true",
audience: "your-api-audience", // Add this line
...mapLoginMethodParamsForUrl(options),
},
});
Make sure to replace
"your-api-audience"
with the actual audience value (usually your API URL).
This ensures your tokens are issued for the correct API. Let me know if you have any questions—happy to help! 🚀
Thanks, doesn't work. I have no error message to show, it simply doesn't find the user when I call
getUser
on the server
I "activated" the registered API from the Kinde dashboard (for both the front-end and the back-end apps)
i doubled checked the API URLs that is regsitered and that I pass in audience (both including https://
)
I logged out and logged in again to make sure the right token is used
Any github repo to look for an example of client and servers talking to each other (outside of NextJS server actions that work out of the box)?Hi Tito, just to confirm—did the user successfully log in on the client side, and is the issue occurring when calling getUser on the Next.js server side?
yes
anything else i can call on server side other than
getUser
to get more info on why it's failing?
maybe i should refresh the accessToken on the client side first?
i tried several times to logout and login to use a new accessToken, same problemAfter the user successfully logs in on Expo, an access token is obtained and stored. When making a request to the Next.js endpoint, you should pass the stored access token in the Authorization header as a Bearer token. Next.js should then validate this token and use it to fetch the required data.
i see the token is correctly transmitted and received server side.
getUser
just returns null
Hi @Tito, Dropping into this conversation.
With the starter kit, it uses the
With the starter kit, it uses the
ExpoSecureStore
from our @kinde/js-utils
library. This unlocked all our helper methods. One of which is getUserProfile
which will get the information form the idToken. This work for you?
As for the getUser not working, your NextJS site is only receiving the access token, not the id token, so it will only know the rights and not the who it is. What are you lookign to achieve here?Client-side, the login is working and i can get the user profile. From the client app, I want to call an api on my NextJS backend
i call it with fetch and pass the
accessToken
in the Authorization: Bearer
header
on the nextjs server side, shouldn't it pick it up using the above code?
i would like the server-side to recognize the accessToken and identify the user calling based on the accessToken
should i pass the idToken instead in Authorization: Bearer {idToken}
?
That doesn't work either
In both cases, if I pass idToken
or accessToken
in the Authorization
header from the client, on the server isAuthenticated
returns false and getUser
returns null
the nextjs app works fine for users logged in on nextjsBecause you're not using the authentication from NextJS, it does not know the context and not setup for the user.
Within the access token you have a sub claim which contains the users Kinde ID. From this you can call the Kinde API to get the users details. For this you will have to create a M2M application within Kinde and setup the relevant scopes for access. Then use the JS Management package (https://github.com/kinde-oss/management-api-js) to request the users details.
GitHub
GitHub - kinde-oss/management-api-js: javascript package for intera...
javascript package for interacting with the Kinde Management API - kinde-oss/management-api-js
Thanks. I previously managed to use M2M API to get a user by email. How do I get users details given an accessToken?
I managed. This should be a very common use case that could be documented or have some utility libraries to actually use it.
I am now facing the question of how to get a long-lived token for the M2M application. I initially struggled because my token had expired
We have made lots of changes and updates to simplify the JS ecosystem over the last few months, docs are catching up.
thanks ok
docs always talk about "test token"
but how do i get a server-to-server token that lasts longer than an hour?
The kinde
managment-api-js
package will handle that for you within your application.The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("@kinde/management-api-js")' call instead.
To convert this file to an ECMAScript module, change its file extension to '.mts', or add the field
"type": "module" to '/Users/.../streckenheldnext/package.json'.
Cursor warning on the import statement
i played around, i can't use this management-api-js
module, not sure if the npm package is the latest version
i don't have the issue with the other kinde packagesI have just tried the package locally on a NextJS project and works with no errors. Could you let me know what NextJS version and package manager you're using please?
WAIT I LITERALLY AM HAVING THE SAME ISSUE AS YOU. Trying to get my expo app to talk to my nextjs for auth
came in here today and searched "Expo"
btw i had to use secure store for this but a bit confused that kinde now has an expo package since last august but not linked in documentaiton anywhere?
just found it on github.
https://github.com/kinde-oss/expo
We are holding off fully pushing the new Expo SDK, there are a few edge cases which are causing frustrations, we are workign with Expo directly along side partners to get this resolved. We have the Expo starter kit which is a unpackaged version of the SDK which works correctly.
Does what is talked about here help you @corwin ?
about to read thru the entire thread and test it out!
Using
npm
10.1.0, react
18.2.0, next
14.1.0
And:
For posterity, this is how I call Kinde Management APIs from a NextJS backend, given a user's accessToken (originally obtained by having the user login on an expo react native app):
i got mine working… i send bearer to my backend and use well-known jwks to verify. but now my expo client can see data from my backend and i have my app working on expo and nextjs web app too
Hi @corwin, great to hear it’s working for you! @Tito, could you confirm if it’s resolved on your end as well? Feel free to reach out if anything else comes up—we’re here to help!
Three outstanding issues for me:
- I can extract user info using m2m from backend, but I don't think the JWT token is "Verified". How do I verify validity of the token from the backend?
- I couldn't figure out how to have a long-lived access token for the M2M api, i only see references to "test-tokens"
- I can't import
management-api-js
due to an error (see above), for now I am just using REST API directly
The problem was maybe related to the fact that I initially started by NextJS backend app by editing [email protected]
which defines a next.config.js
with require
syntax instead of import
i also had to add "type": "module"
to package.json
But the issue is still that Module '"@kinde/management-api-js"' has no exported member 'Users'.
Actually I had to revert it back because there is a chain reaction of other Next packages that can't be imported any more. I can't import management-api-js
because it creates some sort of confusion between ES module and CommonJS module.In your TS config can you update these settings
Thank you, it works now. Notice that in https://github.com/kinde-oss/management-api-js, you should change the docs in Configuration
KINDE_DOMAIN
e.g. https://mybusiness.kinde.com
as the https://
is required. I would call it KINDE_URL
.Great to hear it worked! Let us know if you need anything else—we're here to help.