@pointerra/pointerra-jwt v0.1.6
Pointerra JWT helper
A utility class for the browser that helps manage JWT access and refresh tokens used for authenticating with the Pointerra Data Portal.
The default UMD module should work with Node environments or the usual package bundlers (webpack, parcel etc). For convenience there are also:
- An ES6 module provided in
dist/pointerra-jwt.es6.js
. - A browser version provided in
dist/browser.js
. This attaches the global PointerraJWT instance to thewindow
object.
A simple login form is provided so you can get up and running immediately. It's also possible to bring your own UI for this workflow.
Basic usage (built-in UI)
The main goal of this library is to provide authentication headers for API calls. Use the .headers()
method of the global PointerraJWT
instance to access the header dictionary. Note that this method is asynchronous: you will need to await
it, or use it in a Promise chain.
Using await:
const result = await fetch('https://example-pointerra-service/api/', {
headers: await PointerraJWT.headers(),
})
Using promises:
PointerraJWT.headers().then(function(headers) {
return fetch('https://example-pointerra-service/api/', {
headers: headers
})
}).then(function(fetchResult) {
/* Do something with fetch result */
})
The JWT library will automatically prompt for credentials when required.
Advanced usage
Options can be set on the global PointerraJWT instance:
// These are the defaults and should work for most simple use cases.
PointerraJWT.configure({
endpoint: 'https://app.pointerra.io',
expiryBuffer: 10,
disableLoginDialog: false,
zIndex: 3000,
storage: localStorage,
prefix: "_pjwt_",
expiryCallback: null,
})
Options explained
endpoint
: allows you to configure the endpoint used for authentication. This endpoint must provide valid tokens for the API endpoint you are accessing.expiryBuffer
: tokens will be refreshed with this many seconds remaining until they expire, to account for latency and server load. Try increasing this value if your API requests are failing intermittently.disableLoginDialog
: disables the built-in UI. You will need to provide your own UI and call the appropriate methods yourself.zIndex
: controls the CSSz-index
value of the built-in UI. Modify this to resolve stacking issues when using the built-in UI.storage
: sets the storage backend used for saving tokens. Defaults tolocalStorage
for the browser. Must be an object implementing the Storage API.prefix
: string used to create keys for storing tokens. Used internally for testing.expiryCallback
: if provided, this function will be called when a request is made for the auth headers and the refresh token has expired or is not available. This gives you an opportunity to present your own UI for collecting credentials. See the callBack section, below, for more information.
Available methods
async headers(preventThrow = false)
: return the authentication headers. Will issue arefresh()
call if necessary. Throws aJWTExpiredError
if unable to refresh andpreventThrow
is false. IfpreventThrow
is true and the token has expired or has not been set, this will return empty auth headers, suitable for accessing public API endpoints.async login(username, password)
: submit credentials to the auth endpoint for validation. Returns a boolean indicating success.logout()
: clear all stored data, effectively logging the user out.async prompt()
: manually show the login dialog.async refresh(preventThrow = false)
: manually refresh the access token. Will prompt for new credentials if the refresh token has expired anddisableLoginDialog
is false. Throws aJWTExpiredError
if unable to refresh andpreventThrow
is false.
Available properties
.expired
-boolean
indicating whether the refresh token has expired. Credentials must be resupplied..stale
-boolean
indicating whether the access token has expired. A refresh request will be made automatically..isAuthenticated
:boolean
indicating that a session is active..data
:dictionary
containing some user profile information. The exact contents may change depending on the auth endpoint.
Creating instances
The preferred usage is through the global instance exposed as the default module export, or attached as the global PointerraJWT
object in the browser.
The PointerraJWT
class is also exported and can be imported or required separately. Options can be passed in to the constructor rather than using .configure()
- this allows you to set things like the storage backend and prefix at creation time.
In the browser, to avoid naming issues, you can create new instances using the static .create()
method. This accepts the same options object as .configure()
and returns a new instance.
// Node
const PointerraJWT = require("@pointerrajwt/pointerra-jwt").PointerraJWT
const myJwt = new PointerraJWT({storage: customBackend /* insert your own custom backend here */})
// Browser
const myJwt = PointerraJWT.create({ storage: sessionStorage })
Callbacks
The expiryCallback
option should be a function accepting one parameter (the login function).
It should return true
if login is successful, or false
otherwise. It is recommended to return a promise here, or use an async
function, in which case the resolved value indicates success or failure.
If you are not worried about maintaining state you can simply use this callback to redirect to an external login page.
// Returning a promise
function handleExpiry(loginFn) {
// Show a form here, listen for the submit handler, etc
return new Promise((resolve, reject) => {
// Call the login function with the provided credentials
loginFn(username, password)
.then(result => {
if (result) {
console.log("Logged in")
resolve(true)
} else {
// Retry or reject
}
})
})
}
PointerraJWT.configure({
expiryCallback: handleExpiry,
disableLoginDialog: true,
})