Can the PKCE access token be used to authenticate/authorize requests
Hi,
I am currently using clerk with a chrome extension. I want to switch to a service that supports Oauth PKCE flow. Clerk has it but the access token retrieved from this flow can not be used to authenticate requests.
Does Kinde support PKCE fully? Can the nextjs middleware automatically verify/permit requests with the PKCE access token?
36 Replies
In clerk, the access token isn't a JWT, is it the same in Kinde. I haven't implemented kinde yet because I wanted to make sure it fits my use case by reading the docs. But a few details are missing
Hi @sudhanshug,
Thanks for reaching out and good idea to get your questions answered before attempting to implement Kinde.
Yes, Kinde fully supports the PKCE extension for the Authorization Code flow.
As for your question about Next.js middleware, Kinde provides a Next.js SDK that simplifies the process of setting up authentication (verifying/permitting authentication requests) in your Next.js application - see the following guide: https://kinde.com/docs/developer-tools/nextjs-sdk/
Regarding the access token, Kinde does use JWTs for access tokens. These tokens are used to make authenticated requests on behalf of the user.
I hope this helps. Let me know if you have any other questions.
I am more than happy to give guidance on how to use Kinde for a Chrome Extension with NextJS. Let me know.
Kinde Docs
NextJS App Router SDK v2 - Developer tools - Help center
Our developer tools provide everything you need to get started with Kinde.
Do you have any docs/example project with a chrome extension + nextjs/express with PKCE?
thanks for the reply!
Also, does the Authorization Code flow also provides offline access (refresh token)?
Because this is for a chrome extension, the access token may expire in a while. I dont want the user to re-authorize again and again
I second the request for this example!
Nevermind, I figured out the refresh code situation – still nice to have an example
Hey @sudhanshug and @snusguy123,
Currently we don't have offical docs/examples for building a Chrome Extension with Kinde.
But, I can provide a high-level overview of how you might use Kinde with a Chrome Extension that uses Next.js and Express, with PKCE.
1. Setup Kinde: First, you need to setup Kinde for your application. You can follow the instructions provided in the Kinde Next.js SDK documentation.
2. Create a background script: In your Chrome Extension, you need to create a background script that will handle the authentication process. This script will open a new tab for the Kinde login page and listen for the redirect callback.
3. Handle the authentication: Once the user logs in, Kinde will redirect the user to a callback URL with the authorization code in the URL parameters. Your background script should listen for this redirect, extract the authorization code, and exchange it for an access token using Kinde's token endpoint.
4. Store the access token: After you get the access token, you can store it in the Chrome Extension's local storage. You can then use this token to make authenticated requests to your Next.js API.
5. Use the access token: In your Next.js API routes, you can use Kinde's Next.js SDK to verify the access token and authenticate the request.
Remember, this is a high-level overview and the actual implementation might require additional steps based on your application's specific needs. Also, ensure to handle the tokens securely to prevent any security risks.
Let me know if you have further questions on this.
Sounds like you figured out how to handle offline access, but Ill provide details here anyways so others can reference it.
The Authorization Code flow can provide offline access if you include the
offline
scope in your authentication request. This will return a refresh token along with the access token. You can use the refresh token to obtain a new access token when the current one expires, without requiring the user to re-authenticate. This is particularly useful for maintaining long-running sessions in both back-end and web apps.
Here's an example of how to include the offline
scope in your request:
Remember to replace <yoursubdomain>
, your_client_id
, and your_redirect_uri
with your actual values.
For more information, you can refer to the Kinde documentation on refresh tokens.Thanks!
Here is a gist I created with a working OAuth setup for chrome extension
Gist
Kinde OAuth PKCE setup for chrome extension using plasmo
Kinde OAuth PKCE setup for chrome extension using plasmo - background.ts
Actually, I am not able to get this to work completely. In nextjs, when I call this endpoint with the Authorization Bearer header, I am not able to retrieve the user. It always returns null
@Oli - Kinde, the ENVs are correctly set up
I went through your nextjs sdk, I dont think this is secure https://github.com/kinde-oss/kinde-auth-nextjs/blob/main/src/utils/pageRouter/isTokenValid.js#L4
It seems that you are not verifying the signature of the jwt
GitHub
kinde-auth-nextjs/src/utils/pageRouter/isTokenValid.js at main · ki...
Kinde NextJS SDK - authentication for server rendered apps - kinde-oss/kinde-auth-nextjs
if you are, please point me to it
Can I get an update on this. Kind of important
Hey @sudhanshug,
Apologies for the delay.
If the user is not authenticated, it returns a 401 status code. If the user is authenticated, it logs the user's information and returns it as a JSON response.
If you're not able to retrieve the user and it always returns null, it could be due to a few reasons:
1. The user is not authenticated: The
isAuthenticated
function checks if the user is authenticated. If the user is not authenticated, the function will return false, and the getUser
function will not be called.
2. The JWT token is not included in the request headers: The getKindeServerSession
function retrieves the user's information from the JWT token included in the request headers. If the JWT token is not included in the headers, the function will not be able to retrieve the user's information.
3. The JWT token is invalid or expired: If the JWT token is invalid or expired, the getKindeServerSession
function will not be able to retrieve the user's information.
To debug this issue, you could add some logging to your function to check the value of isAuthenticated and the request headers. This might give you some clues about what's going wrong.
I understand your concern about the security of the JWT validation in the Next.js SDK. The function you're referring to, isTokenValid
, is a utility function that checks if the token exists and if it's not expired. It doesn't verify the signature of the JWT.
The actual verification of the JWT signature is handled by the Kinde server when you make a request to a protected resource. The server uses the public key corresponding to the private key that signed the JWT to verify the signature. This ensures that the token was issued by Kinde and hasn't been tampered with.if I am getting this right, the nextjs sdk hits the kinde server on every request to a protected resource?
Yes, you're correct. The Next.js SDK does communicate with the Kinde server on every request to a protected resource. This is done to validate the user's session and ensure they have the necessary permissions to access the resource. The
getKindeServerSession
function, which is used in the Next.js SDK, retrieves the user's session data from the Kinde server. This includes the user's authentication status, permissions, and other user-related data. If the user is not authenticated or does not have the necessary permissions, the request to the protected resource will be denied. This helps to maintain the security and integrity of your application.Ok thanks.
Re: next js sdk returning 401
Can you please confirm for me that your nextjs sdk automatically reads the Authorization Bearer token and correctly authenticates the request?
Asking because when I read your codebase, it seemed to rely on the cookie solely and did not seem to read Authorization header at all.
The Next.js SDK primarily uses cookies for session management and does not automatically read the Authorization Bearer token from the request headers. The
getKindeServerSession
function retrieves the session data from the cookies. If you want to authenticate requests using the Authorization Bearer token, you would need to implement that manually in your application.
Let me know if you want guidance on how to implement that manually in your application.Okay. I know how I can verify and decode the token.
But how will I get all the goodies then like middleware, feature flags, orgs etc.
Let me get back to you on this @sudhanshug
Well I figured that out as well.
Maybe you should mention here that /api/auth/* should not be secured by the nextjs middleware (I was getting too many redirects before)
But how will I get all the goodies then like middleware, feature flags, orgs etc.Sounds like you already figured that out. But I'll provide my answer anyway for your (or others) reference. The Next.js SDK provides you with all the features you need, including middleware, feature flags, and organization management. For middleware, you can use the
getKindeServerSession
function in the Next.js SDK to authenticate requests and manage user sessions.
For feature flags, when a user signs in, the access token your application receives contains a custom claim called feature_flags
which is an object detailing the feature flags for that user. You can set feature flags in your Kinde account and use helper functions provided by the SDK to easily access these feature flags.
You can read more details about this here in the Next.js documentationKinde Docs
NextJS App Router SDK v2 - Developer tools - Help center
Our developer tools provide everything you need to get started with Kinde.
Great feedback. I will pass this onto my team.
I am tagging my teammate @onderay04 in this conversation since I will be away next week, but Andre can answer any question you may have while Im away.
Keep the questions coming! We are here to help!
Kinde's openid implementation seems to be incorrect.
When I use refresh token with
/oauth2/token
endpoint, it generates a new id_token whose auth_time is not the same as the original id token.
https://arc.net/l/quote/oruyybpitoken refresh fails as a result of this when using the
oidc-client-ts
js lib
looks like the new id token's auth_time
is equal to iat
weirdly, this only seems to happen when the access token has expired.
I am not sure about this – but there is definitely some erratic behaviourI've gotten the same thing, failed refresh for the access token from
oidc-client-ts
.
For me though, the refresh endpoint fails./oauth2/token is the refresh endpoint
getting the exact same issue.
i reckon it's one line of code which regenerates auth_time in the refresh logic instead of just copying the old one over; because someone reckoned for oidc that the auth time is relevant to the creation of the information and not the creation of the token
oh BTW - removing
oidc
from scopes solves this seemingly
(I think?)hi @snusguy123 and @sudhanshug , we're still investigating the issue with the
auth_time
claim in the id token being incorrect when refreshing. We'll provide an update as soon as we have more information.I seem to get this upon trying to refresh with OIDC (openid)
Hi guys, any updates on this so far? Been nearly a cuppa weeks 😛
We are still looking into it, as whatever is causing the issue for you is super deep.
are you guys able to reproduce it for yourselves or would it help if i tried to make a guide to reproducing it?
Thanks for the offer. We can reproduce it, but finding where it is coming from is taking a bit of testing.
no problem, thanks for the effort. Not in any rush to fix it, don't need OIDC rn and I'm not even deployed to customers RN so not costing me anything. Let me know (either via DM or here) if there's anything you need.
I believe this has been fixed, given that I am not getting the same error when refreshing after adding openid to all of my scopes in my application. Thanks guys 🙂
Good to hear this has been fixed.
Please let us know if you come across any other issues.