neo4j / neo4j-javascript-driver

Neo4j Bolt driver for JavaScript
https://neo4j.com/docs/javascript-manual/current/
Apache License 2.0
839 stars 148 forks source link

Improve `AuthTokenManager` interface and factory method #1123

Closed bigmontz closed 10 months ago

bigmontz commented 11 months ago

⚠️ This API is released as preview.

Currently, the AuthTokenManager is designed to handle token expiration only. The AuthTokenManager interface only has methods to receive notifications on security errors related to token expiration: AuthTokenManager.onTokenExpired. The provided implementation neo4j.expirationBasedAuthTokenManager is built to support only token expiration. However, we also want to cater for password rotation scenarios.

Factory Method Changes

Expiration based and bearer tokens

The method neo4j.expirationBasedAuthTokenManager was renamed and moved to neo4j.authTokenManagers.bearer.

import neo4j, { AuthToken } from 'neo4j-driver'

/**
 * Method called whenever the driver needs to refresh the token.
 *
 * The refresh will happen if the driver is notified by the server
 * about a token expiration or if the `Date.now() > tokenData.expiry`
 *
 * Important, the driver will block all the connections creation until
 * this function resolves the new auth token.
 */
async function fetchAuthTokenFromMyProvider () {
   const bearer: string = await myProvider.getBearerToken()
   const token: AuthToken = neo4j.auth.bearer(bearer)
   const expiration: Date = myProvider.getExpiryDate()  
   return {
      token,
      // if expiration is not provided, 
      // the driver will only fetch a new token when a failure happens
      expiration 
   }
}

const driver = neo4j.driver(
    'neo4j://localhost:7687', 
    neo4j.authTokenManagers.bearer({ 
        tokenProvider: fetchAuthTokenFromMyProvider 
    })
)

Password rotation and basic auth

neo4j.authTokenManagers.basic was added to handle password rotation with AuthTokenManager.

import neo4j, { AuthToken } from 'neo4j-driver'

/**
 * Method called whenever the driver needs to refresh the token.
 *
 * Important, the driver will block all the connections creation until
 * this function resolves the new auth token.
 */
async function fetchMyUserAndPassword () {
   const { user, password } = await myProvider.getUserAndPassword()
   return neo4j.auth.basic(user, password)  
}

const driver = neo4j.driver(
    'neo4j://localhost:7687', 
    neo4j.authTokenManagers.basic({ 
        tokenProvider: fetchMyUserAndPassword 
    })
)

Development checklist

⚠️ This API is released as preview.