diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts
index a3db0439d8bdfd2d2ab5ed2b1ee404bba486dff2..fac476e3d72e90cbb8435776ac94cb377ba9a452 100644
--- a/pages/api/auth/[...nextauth].ts
+++ b/pages/api/auth/[...nextauth].ts
@@ -1,9 +1,49 @@
 import NextAuth from 'next-auth'
 import KeycloakProvider from 'next-auth/providers/keycloak'
-// import { UnstorageAdapter } from '@auth/unstorage-adapter'
-// import { createStorage } from 'unstorage'
 
-// const storage = createStorage()
+const clientId = 'gwdg-fdoman-test'
+const clientSecret = process.env.KEY_CLOAK_CLIENT_SECRET || ''
+const issuer = 'https://keycloak.sso.gwdg.de/auth/realms/academiccloud'
+
+async function refreshAccessToken (token: any) {
+  try {
+    const url =
+      issuer + '/protocol/openid-connect/token?' +
+      new URLSearchParams({
+        client_id: clientId,
+        client_secret: clientSecret,
+        grant_type: 'refresh_token',
+        refresh_token: token.refreshToken
+      }).toString()
+
+    const response = await fetch(url, {
+      headers: {
+        'Content-Type': 'application/x-www-form-urlencoded'
+      },
+      method: 'POST'
+    })
+
+    const refreshedTokens = await response.json()
+
+    if (!response.ok) {
+      throw refreshedTokens
+    }
+
+    return {
+      ...token,
+      accessToken: refreshedTokens.access_token,
+      accessTokenExpires: Date.now() + refreshedTokens.expires_in * 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 = {
   // adapter: UnstorageAdapter(storage),
@@ -15,12 +55,9 @@ export const authOptions = {
   providers: [
     // !!! Should be stored in .env file.
     KeycloakProvider({
-      // clientId: 'fdo-manager-webui',
-      clientId: 'gwdg-fdoman-test',
-      // clientSecret: 'ay7l6jhECSohAZsEp6HYOaoXdARMQCei',
-      clientSecret: process.env.KEY_CLOAK_CLIENT_SECRET || '',
-      // issuer: 'http://localhost:8000/auth/realms/fdo-manager',
-      issuer: 'https://keycloak.sso.gwdg.de/auth/realms/academiccloud',
+      clientId,
+      clientSecret,
+      issuer,
       // authorization: { params: { scope: 'openid profile email' } },
       profile (profile) {
         console.log('### profile', profile, '### ### ###')
@@ -38,10 +75,12 @@ export const authOptions = {
     },
     async session ({ session, user, token }: any) {
       console.log('### session', session, user, token, '### ### ###')
-      return {
-        ...session,
-        account: token.account
-      }
+
+      session.user = token.user
+      session.accessToken = token.accessToken
+      session.error = token.error
+
+      return session
     },
     async redirect ({ url, baseUrl }: any) {
       console.log('### redirect', url, baseUrl, '### ### ###')
@@ -49,13 +88,24 @@ export const authOptions = {
     },
     async jwt ({ token, user, account, profile, isNewUser }: any) {
       console.log('### jwt', token, user, account, profile, isNewUser, '### ### ###')
-      if (account) {
+
+      // Initial sign in
+      if (account && user) {
         return {
-          ...token,
-          account
+          accessToken: account.access_token,
+          accessTokenExpires: Date.now() + account.expires_in * 1000,
+          refreshToken: account.refresh_token,
+          user
         }
       }
-      return token
+
+      // 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)
     }
   },
   secret: 'UItTuD1HcGXIj8ZfHUswhYdNd40Lc325R8VlxQPUoR0='