Undefined refresh token

Hello,

I can’t get a refresh token. It returns undefined.

Thank you!

import NextAuth from 'next-auth'
import OktaProvider from 'next-auth/providers/okta'
import axios from 'axios'


/**
 * Takes a token, and returns a new token with updated
 * `accessToken` and `accessTokenExpires`. If an error occurs,
 * returns the old token and an error property
 */
async function refreshAccessToken(token) {
  try {
    const OKTA_ISSUER = process.env.OKTA_ISSUER
    const url = new URL(`${OKTA_ISSUER}/v1/token`)
    url.searchParams.set('client_id', process.env.OKTA_CLIENT_ID)
    url.searchParams.set('client_secret', process.env.OKTA_CLIENT_SECRET)
    url.searchParams.set('grant_type', 'refresh_token')
    url.searchParams.set('refresh_token', token.refreshToken)

    const response = await fetch(url, {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cache-Control': 'no-cache',
        'Authorization': `Bearer ${token.id}`
      },
      method: 'POST'
    })

    const refreshedTokens = await response.json()

    if (!response.ok) {
      throw refreshedTokens
    }

    return {
      ...token,
      accessToken: refreshedTokens.access_token,
      accessTokenExpires: Date.now() + refreshedTokens.expires_at * 1000,
      refreshToken: refreshedTokens.refresh_token ?? token.refreshToken // Fall back to old refresh token
    }
  } catch (error) {
    console.log(error)

    return {
      ...token,
      error: 'RefreshAccessTokenError'
    }
  }
}

export const authOptions ={
  // Configure one or more authentication providers
  providers: [
    OktaProvider({
      clientId: process.env.OKTA_CLIENT_ID,
      clientSecret: process.env.OKTA_CLIENT_SECRET,
      issuer: process.env.OKTA_ISSUER
    })
    // ...add more providers here
  ],
  callbacks: {
    async session({ session, token }) {
      session.id = token.id
      session.user = token.user
      // Add header to axios.
      axios.defaults.headers.common.Authorization = `Bearer ${token.id}`
      return session
    },
    async jwt({ token, user, account }) {
      // Initial sign in
      if (account && user) {
        token.id = account.id_token 
        return {
          id: account.id_token,
          accessToken: account.access_token,
          accessTokenExpires: Date.now() + account.expires_at * 1000,
          refreshToken: account.refresh_token,
          user
        }
      }
      
      // Return previous token if the access token has not expired yet
      if (Date.now() < token.accessTokenExpires) {
        return token
      }

      // Access token has expired, try to update it
      return refreshAccessToken(token)
    }
  },
  jwt: {
    encryption: false
  }
}

export default NextAuth(authOptions)

Should I need to pass the scope parameters as params to get refresh token?

scope=offline_access openid profile

Yup, you need to add the offline_access scope to your /authorize request to get a refresh token back, but also double check that the app is configured to support the “Refresh token” grant type, otherwise you won’t get one back even if you request it.

Thank you @andrea I have already done that and I am now able to get refresh tokens.