pintoderian / next-directus-auth-ts

Template for project structure with nextjs 14 - next auth - directus and typescript
MIT License
44 stars 5 forks source link

API call in dashboard #6

Closed DutchCloud4Work closed 3 months ago

DutchCloud4Work commented 6 months ago

Hi,

This is not an issue, but how can I make an API call using the current token in for example the dashboard page? I made an directus.js helper file (as shown on their site) but I can`t get the token / auth to work.

For example, I made an collection "global" with read right for one user (the one I log in with). At the moment I`m getting the error not authorized..

Sorry for this noob question :-)

R1NEJ0 commented 5 months ago

+1

R1NEJ0 commented 5 months ago

I've been reading about directus sdk.

In theory if you use directus as @pintoderian

image

You will be able making request like this

const res = await directus().request(readItems('my_collection', {
    fields: ['*']}))

because nextauth save token in the client as they says in their docs: https://docs.directus.io/guides/sdk/authentication.html

image

But I am not able to use like this... if you put your access token as parameter (you can get it from the session for example)

 const res = await directus("my_token").request(readItems('my_collection', {
    fields: ['*']}))

MAGIC! Then you can access to your api.

The main problem is how to manage refresh token as I said in theory directus sdk can manage it by itselft but I am not able to make it works... nextauth doesnt seems to be able to reload token...

Don't forget put make your TS collections, to avoid TS error. You can use:

 npx directus-typescript-gen --host http://localhost:8055 --email ADMIN_EMAIL --password ADMIN_PASSWORD --typeName 
 ApiCollections --outFile api-collection.d.ts

from: https://www.izoukhai.com/blog/generate-typescript-definitions-from-directus

pintoderian commented 5 months ago

I just fixed the refresh in nextauth and gave the session the access_token attribute so you can use that token when making requests in directus. Example:

const session = await getServerSession(options)
const token = session?.access_token
const api = directus(token)

The const api = directus(token) is calling the directus.ts file in the services folder

Login now goes hand in hand with directus env:

#The length of validity of the access token ["15m"]
ACCESS_TOKEN_TTL="5m"
# The duration of the refresh token's validity and also the time that users stay logged in to the application ["7d"]
REFRESH_TOKEN_TTL="10m"
nicksergeant commented 2 months ago

@pintoderian I'm curious what the purpose of this fallback is in services/directus.ts:

  return createDirectus(process.env.NEXT_PUBLIC_DIRECTUS_API ?? "")
    .with(
      authentication("cookie", { credentials: "include", autoRefresh: true })
    )
    .with(rest({ credentials: "include" }))

If you're pulling the access_token from the session and using that to make requests with:

    return createDirectus(process.env.NEXT_PUBLIC_DIRECTUS_API ?? "")
      .with(staticToken(token))
      .with(rest())

Is the cookie fallback needed?

nicksergeant commented 2 months ago

As a side-note, I'm not able to get API requests w/ cookie auth to work at all like this:

  const api = directus()

  const places = await api.request(
    readItems("places", {
      sort: "name",
    })
  )

Even after logging in successfully and seeing the cookies being set, the requests to Directus in this fashion always come back forbidden on permissions.

I guess I'm concerned about using the following strategy since we'll need to manually refresh the access_token?

    return createDirectus(process.env.NEXT_PUBLIC_DIRECTUS_API ?? "")
      .with(staticToken(token))
      .with(rest())

After the ACCESS_TOKEN_TTL timeout, this does start failing:

{
  user: { name: undefined, email: undefined, image: undefined },
  error: 'RefreshAccessTokenError'
}

Actually I'm guessing creating the Directus client from cookie should only work client-side in Next.js, not server-side, which is what I was attempting.

I'm still at a loss for how to make Directus API calls with the user's credentials via server actions... maybe I need to refresh the token on every single API call on the server?