Hello, I am trying to get permit elements to work...
# permit-saas
y
Hello, I am trying to get permit elements to work. But i cant get it to work. Even when using the documentation.
a
Hi @Yorrick Elzinga, I'm an AI assistant for Permit.io. I'll analyze available sources and get back to you shortly.
p
Hey, thanks for reaching out ! It seems our team is a little busy right now, a human will be with you within the next hour or so. In the meantime, can I help you ?
a
I can help you troubleshoot Permit Elements. Here are the key implementation steps to check: Prerequisites You need to install the permit-js package

(1) ▾

:
Copy code
npm install permit-js
or
Copy code
yarn add permit-js
Backend Configuration Create a backend route for the login endpoint :
Copy code
permit.elements.loginAs
This function takes two parameters: the current user ID/email and the tenant . Frontend Configuration In your frontend, import Permit and set up the login function :
Copy code
permit.elements.login
You need to pass the login URL (your backend endpoint) and specify the login method (cookie, bearer token, or HTTP security header) . Common Issues to Check 1. ​*Missing /login_elements request*​ - If you don't see this request in your Network tab after login, the login method isn't implemented correctly (2) . 2. ​*404/422 errors*​ - Make sure you're sending the correct response format from your backend :
Copy code
res.status(200) .send(ticket.content) ; // CORRECT: sending ticket.content
3. ​*CORS issues*​ - Configure your server to allow requests from your frontend :
Copy code
res.header("Access-Control-Allow-Origin", "<http://localhost:3001>") ; // update to match the domain you will make the request from
res.header("Access-Control-Allow-Credentials", "true") ;
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Permit-User-Key") ;
4. ​*Cookie blocked*​ - Check if third-party cookies are enabled in your browser settings . 5. ​*401 Unauthorized on /me endpoint*​ - This indicates the user isn't logged in, session expired, or invalid environment key/id . Look for the
permit_session
cookie in the Request Headers . To help debug further, check the Developer Tools Network tab for the
/login_elements
and
/me
requests .
To learn more, see the sources I considered: [[1] Working with Permit Elements - Full Tutorial](

https://www.youtube.com/watch?v=xGYdDF65lkQ▾

) [[2] Troubleshooting](https://docs.permit.io/embeddable-uis/troubleshooting)
y
permit.elements.loginAs Property 'loginAs' does not exist on type 'Elements'. Did you mean 'login'?ts(2551)
loginAs doenst seem to exist anymore
@Ask Inkeep loginAs doenst seem to exist anymore
a
Thanks for tagging me @Yorrick Elzinga. I'll look through relevant sources and get back to you shortly.
You're correct -
loginAs
is a ​*server-side*​ method, not a client-side method. Here's the correct implementation: Server-side (Backend) The
loginAs
method exists on the server-side Permit instance (1) :
Copy code
const { Permit } = require("permitio") ;
const permit = new Permit({token: "<YOUR_API_KEY>", ...}) ;

// In your backend route
const ticket = await permit.elements.loginAs({userId: user_key, tenantId: TENANT}) ;
For Python :
Copy code
from permitio import Permit
permit = Permit(token="<YOUR_API_KEY>", ...)

# In your backend route
ticket = await permit.elements.login_as(USER, TENANT)
Client-side (Frontend) On the frontend, you use the
login
method from permit-js :
Copy code
permit.elements.login({
  loginUrl: '<https://your_app_url.com/login_cookie>',
  tenant: 'your_tenant_key',
  loginMethod: LoginMethod.cookie
})
The TypeScript error you're seeing suggests you're trying to use
loginAs
on the frontend Permit instance, but it only exists on the backend SDK. The frontend only has the
login
method available .
To learn more, see the sources I considered: [[1] Login Method](https://docs.permit.io/embeddable-uis/element-login)
y
@Ask Inkeep what is the api key? const permit = new Permit({token: "<YOUR_API_KEY>", ...}) ;
a
Thanks for tagging me @Yorrick Elzinga. I'll look through relevant sources and get back to you shortly.
The API Key is a secret credential that authenticates your application with Permit.io (1) . It's required to initialize the Permit SDK and connect your app to Permit's authorization services (2) . ​*How to get your API Key:*​ 1. Open the Permit Dashboard and go to the ​*Projects*​ screen (1) 2. Select your Project and Environment 3. Click the three dots menu in the top-right corner of the environment card 4. Choose ​*Copy API Key*​ from the dropdown menu Alternatively, you can go to ​*Settings -> API Keys*​ in the dashboard (3) . ​*Types of API Keys:*​ There are 3 types : • ​*Organization API Keys*​ - can act on your entire workspace • ​*Project API Keys*​ - can access a single project and its environments • ​*Environment API Keys*​ - can access a single environment (only this type works with PDPs) ​*Using the API Key in your code:*​
Copy code
const permit = new Permit({
  token: "[YOUR_API_KEY]",
  pdp: "<http://localhost:7766>"
}) ;
(2) Replace
[YOUR_API_KEY]
with the actual key you copied from the dashboard . Keep this key secure and never expose it in client-side code.
To learn more, see the sources I considered: [[1] Use the Permit API and SDK](https://docs.permit.io/overview/use-the-permit-api-and-sdk) [[2] Node.js SDK Quickstart](https://docs.permit.io/sdk/nodejs/quickstart-nodejs) [[3] Using the API](https://docs.permit.io/api/api-with-cli)
o
Hi @Yorrick Elzinga let us know if the suggestions here helped you, or if you still need more help
y
I really could use some assistence, been working it for some time, i am really stuck at the moment.
o
What's not working for you?
y
The element is only showing loading identity
I cant seem to figure out how to make a correct header or cookie
o
What kind of login method are you going for?
y
I am using a next.js app and using nextauth for logging in the app, then im syncing the user into permit. Dont really know if i should be using serverside or client side
o
Client side is simpler if you don't need server side I'd stick with that https://docs.permit.io/embeddable-uis/element-login#-client-side-login-method
y
I would like the easiest way indeed. What should be my url just the localhost:3000?
o
Use that with frontendOnly
y
Alright so no loginurl is needed then
Should i just try this in a random page?
o
Your choice ☺️
y
I have
o
Good 👍😊
y
If this is my generated i frame : <iframe title="Permit Element user-management" src="https://embed.permit.io/user-management?envId=4e9eb067dd114f51950886a823c76c4b&amp;darkMode=false" width="100%" height="100%" style="border: none;"/> My env id shoudl be : 4e9eb067dd114f51950886a823c76c4b right?
o
Correct
y
Now i stille have to figure out my user jwt token
o
That should be part of your authentication for your app (nextauth)
y
Hmm well then i am stuck there, cause when i login i have some cookies from nextauth is that it?
o
It should be part of the session object you get from the login callback
Though I'd admit I haven't used nextauth myself
y
{ "user_id": "ad8b396a-fc3a-4825-a135-921dc68b3a1f", "email": "yorrickrb@gmail.com", "tenant": "aichatbot", "env": "4e9eb067dd114f51950886a823c76c4b", "iat": 1758746198, "exp": 1758749798 }
If this is my payload
Is that good?
o
No it's missing the JWT signature fields
y
u mean thtese ? { "alg": "RS256", "kid": "my-key-id", "typ": "JWT" }
o
Yes, as well as the signature itself
I suggest you read up a little bit on JWTs before continuing here 😇
Alternatively if you prefer you can do the serverside option
y
Thnx. Do i need to get the jwk via nextauth ?
which i need to configure in permit
o
The JWK and JWT must match, so unless it's provided to both by a 3rd party than yes
y
Hmm, do you think it woudl be easier for me to use serverside option?
o
If you feel comfortable with adding a backend route and implementing a simple login or secret check for it then yes
y
Could i keep the login flow using nextauth, and create a jwt when logging in and use that?
t
next.js support jwt based login, instead of reinventing the wheel you can configure your app to use it.
that way you get the jwt for free
y
I think i am already using that: export const { handlers, signIn, signOut, auth } = NextAuth({     adapter: DrizzleAdapter(db),     providers: [         GitHub,         Google,         Gitlab({             profile(profile) {                 return {                     ...profile,                     id: profile.id.toString(),                 };             },         }),     ],     debug: false,     session: {         strategy: 'jwt',     },     callbacks: {         async jwt({ token, user }) {             // Voeg userId en email toe aan het JWT             if (user) {                 token.userId = user.id;                 token.email = user.email;             }             return token;         },         async session({ session, token }) {             // Zet deze claims ook op de sessie (voor gebruik in de frontend)             if (session.user) {                 session.user.id = (token.userId ?? '') as string;                 session.user.email = (token.email ?? '') as string;             }             return session;         },     },     events: {         async createUser({ user }) {             // Trigger sync to Permit.io asynchronously (non-blocking)             try {                 console.warn('Syncing user with Permit.io:', user);                 // Ensure required fields exist before syncing                 if (!user.id || !user.email) {                     console.error('User missing required fields for Permit.io sync:', {                         id: user.id,                         email: user.email,                     });                     return;                 }                 await permit.api.users.sync({                     key: user.id,                     email: user.email,                     first_name: user.name ?? '',                 });             } catch (err) {                 console.error('Error syncing with Permit.io:', err);             }         },     }, });
t
Copy code
session: {
        strategy: 'jwt',
    },
yes, looks like it
nextauth.js save the full jwt in a cookie and they have a helper function to get it as well: https://next-auth.js.org/configuration/options#jwt-helper
this is the JWT you should use
actually lookin at their docs, they don't support the jwks format. NextAuth.js uses symmetric HS512 keys by default, which are not suitable for JWKS endpoints since JWKS is designed for public key cryptography
@Yorrick Elzinga
Could i keep the login flow using nextauth, and create a jwt when logging in and use that?
Yes, I think that will be the easiest. you can use the
jsonwebtoken
library
there is also
jose
y
Oh damn, just had this kinda working have this token now: "token": { "name": "Yorrick Elzinga", "email": "yorrickrb@gmail.com", "picture": "https://lh3.googleusercontent.com/a/ACg8ocK1dxW0FNZFrr5MCBpP1ptBU-orWy5Qxp4iEa59wRnb3e2mhQ=s96-c", "sub": "ad8b396a-fc3a-4825-a135-921dc68b3a1f", "userId": "ad8b396a-fc3a-4825-a135-921dc68b3a1f", "iat": 1758747717, "exp": 1761339717, "jti": "112b605b-c82e-42d1-b64b-a5aefc5e497d" }
@Thomas is this a correct jwt? eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX2lkIjoiYWQ4YjM5NmEtZmMzYS00ODI1LWExMzUtOTIxZGM2OGIzYTFmIiwiZW1haWwiOiJ5b3JyaWNrcmJAZ21haWwuY29tIiwidGVuYW50IjoiYWljaGF0Ym90IiwiZW52IjoiNGU5ZWIwNjdkZDExNGY1MTk1MDg4NmE4MjNjNzZjNGIiLCJpYXQiOjE3NTg3NDkxNTgsImV4cCI6MTc1ODc1Mjc1OH0.YBbS-anfAuT2q0zPevG9L9UouekzHxSlk7OVEW9fH01vlmqN3lgOcAbYYcqzty08D-CtGN8aY42S9avGjcn9cpSHJgL1PEEkgGbSKFhliMoyd1ohbWdH_5I2tQG3KpA9CiTaOPxnTf_TWK5JRqYN2RJIURMZ5eNFKNkM_QM4FG7b5WVKONsGlEEOTNazd1RzKqVeos2ss4tMYcuSCDz6_XfvjVsovTu33wF6mU_2D_Fuirc0o_3uuFbFXkj6uzyuictUb_IqzW49CPxobwFXhOYZUPgFqH7NI-3U-hej_1vm7TZ6JgzlKfRei1mH8o9gDmLvoqWYg3AEQG2e70vXRw
this is the payload { "user_id": "ad8b396a-fc3a-4825-a135-921dc68b3a1f", "email": "yorrickrb@gmail.com", "tenant": "aichatbot", "env": "4e9eb067dd114f51950886a823c76c4b", "iat": 1758749158, "exp": 1758752758 }
t
looks right
y
When i am not showing the iframe i have no errors at the moment
As soon as i want to show my iframe i get some errors
GET https://4e9eb067dd114f51950886a823c76c4b.embed.api.permit.io/v2/auth/me 401 (Unauthorized) fetchApi @ runtime.ts:188 request @ runtime.ts:122 await in request meRaw @ AuthenticationApi.ts:512 me @ AuthenticationApi.ts:529 queryFn @ getLoggedInUser.ts:20 fetchFn @ query.js:300 c @ retryer.js:95 u @ retryer.js:156 t.fetch @ query.js:332 n.executeFetch @ queryObserver.js:199 n.onSubscribe @ queryObserver.js:40 t.subscribe @ subscribable.js:16 (anonymous) @ useBaseQuery.js:60 ru @ react-dom.production.min.js:243 wl @ react-dom.production.min.js:285 (anonymous) @ react-dom.production.min.js:281 w @ scheduler.production.min.js:13 R @ scheduler.production.min.js:14
Copy code
'use client';
import { useEffect } from 'react';
import permit, { LoginMethod } from '@permitio/permit-js';

export default function PermitLogin() {
    useEffect(() => {
        async function loginWithPermit() {
            try {
                const res = await fetch('/api/user-jwt');
                const data = await res.json();
                if (!data.token) {
                    console.error('No JWT found');
                    return;
                }
                await permit.elements.login({
                    // loginMethod: LoginMethod.frontendOnly,
                    // userJwt: data.token,
                    // tenant: 'aichatbot',
                    // envId: '4e9eb067dd114f51950886a823c76c4b',
                    loginMethod: LoginMethod.cookie,
                    loginUrl: '<http://localhost:3000/api/user-jwt>',
                    tenant: 'aichatbot',
                });
                console.log('Permit login success');
            } catch (err) {
                console.error('Permit login error', err);
            }
        }
        loginWithPermit();
    }, []);

    return (
        <iframe
            title="Permit Element user-management"
            src="<https://embed.permit.io/user-management?envId=4e9eb067dd114f51950886a823c76c4b&darkMode=false>"
            width="100%"
            height="600"
            style={{ border: 'none' }}
        />
    );
    
}
I feel like everything is correct right now
But im still getting console errors in browser runtime.ts:188 GET https://4e9eb067dd114f51950886a823c76c4b.embed.api.permit.io/v2/auth/me 401 (Unauthorized) fetchApi @ runtime.ts:188 request @ runtime.ts:122 await in request meRaw @ AuthenticationApi.ts:512 me @ AuthenticationApi.ts:529 queryFn @ getLoggedInUser.ts:20 fetchFn @ query.js:300 c @ retryer.js:95 u @ retryer.js:156 t.fetch @ query.js:332 n.executeFetch @ queryObserver.js:199 n.onSubscribe @ queryObserver.js:40 t.subscribe @ subscribable.js:16 (anonymous) @ useBaseQuery.js:60 ru @ react-dom.production.min.js:243 wl @ react-dom.production.min.js:285 (anonymous) @ react-dom.production.min.js:281 w @ scheduler.production.min.js:13 R @ scheduler.production.min.js:14 query.js:358 ResponseError: Response returned an error code at I.request (runtime.ts12611) at async I.meRaw (AuthenticationApi.ts51211) at async I.me (AuthenticationApi.ts52911) onError @ query.js:358 h @ retryer.js:67 (anonymous) @ retryer.js:132 Promise.catch c @ retryer.js:116 u @ retryer.js:156 t.fetch @ query.js:332 n.executeFetch @ queryObserver.js:199 n.onSubscribe @ queryObserver.js:40 t.subscribe @ subscribable.js:16 (anonymous) @ useBaseQuery.js:60 ru @ react-dom.production.min.js:243 wl @ react-dom.production.min.js:285 (anonymous) @ react-dom.production.min.js:281 w @ scheduler.production.min.js:13 R @ scheduler.production.min.js:14 EmbedManager.tsx:32 couldn't fetch current user ResponseError: Response returned an error code at I.request (runtime.ts12611) at async I.meRaw (AuthenticationApi.ts51211) at async I.me (AuthenticationApi.ts52911)
Could anyone help me? On login i am creating a cookie permit_session which i should have according to documentation. But it still is saying {"detail":"An authorization header or login cookie is required"}
p
Hey, thanks for reaching out ! It seems our team is a little busy right now, a human will be with you within the next hour or so. In the meantime, can I help you ?
y
Now having this in my browser console : Element iframe with hhttps://embed.permit.io/user-management?envId=4e9eb067dd114f51950886a823c76c4b&amp;darkMode=false not found retrying in 1200ms
t
Hey @Yorrick Elzinga have you tried this demo: https://github.com/permitio/permit-demo-element it's live at https://permit-demo-element.vercel.app/. You should be able to follow all the calls on that site.
y
I have checked it out before yeah, At the moment i am getting several 404 issues with the permitio/permitjs node module: GET /_next/static/src/permit.ts 404 in 4400ms nextjs-dev | GET /_next/static/src/sendToken.ts 404 in 4413m Already tried to remove the node modules and re installing