@edvizion/auth
v0.6.4
Published
Browser authentication for Edvizion applications.
Readme
Edvizion Auth SDK
Browser authentication for Edvizion applications.
The SDK handles:
- OAuth authorization with PKCE
- Persistent sessions across full-page navigations
- Automatic access-token refresh
- Automatic
Authorizationheaders on same-originfetch()requests - Cached, validated user identity information
- Login and callback web components
Application code never needs direct access to OAuth tokens.
Initialize
Initialize Edvizion Auth as early as possible in your application's entrypoint:
import { Init } from "@edvizion/auth";
Init(
"YOUR_CLIENT_ID",
"https://your-app.com/auth/callback",
"https://your-auth.authkit.app",
);Init() immediately installs the fetch() interceptor, then restores or refreshes the existing authentication session.
Load Edvizion Auth before application code
Because static imports execute before the body of the importing module, applications that may perform fetch() calls during module initialization should load application code dynamically after Init():
import { Init } from "@edvizion/auth";
Init(
"YOUR_CLIENT_ID",
"https://your-app.com/auth/callback",
"https://your-auth.authkit.app",
);
await import("./app");You do not need to wait for Init() before loading the app. Any intercepted requests will wait until authentication initialization completes.
Making API requests
Use the normal browser fetch() API:
const response = await fetch("/api/me");If the user has an authenticated session, Edvizion Auth automatically sends:
Authorization: Bearer <access-token>If the access token has expired, the SDK refreshes it before the request is sent.
Multiple simultaneous requests share the same refresh operation.
Same-origin requests only
By default, Edvizion Auth only adds authentication to requests whose origin matches the current page.
For example, from:
https://recreq.comthis is authenticated:
fetch("/api/students");and this is not:
fetch("https://some-other-service.com/api");This prevents Edvizion credentials from accidentally being sent to third parties.
Signing in
Web component
Use the provided <edvizion-login> component:
<edvizion-login>
<button>Sign In</button>
</edvizion-login>Clicking the component starts the OAuth sign-in flow.
Programmatically
You can also call Login() directly:
import { Login } from "@edvizion/auth";
await Login();This redirects the browser to the configured Edvizion authentication provider.
OAuth callback
Configure your OAuth application's redirect URI to point to a callback page in your application, for example:
https://recreq.com/auth/callbackThe callback URL passed to Init() must match the OAuth application's configured redirect URI.
Using the callback component
The easiest callback page is:
<edvizion-auth-callback redirect-to="/">
</edvizion-auth-callback>The component will:
- Read the OAuth
codeandstate. - Validate the OAuth transaction.
- Exchange the authorization code.
- Persist the new session.
- Load and cache the authenticated identity.
- Redirect to
redirect-to.
If redirect-to is omitted, it redirects to /.
Programmatically
You can alternatively handle the callback yourself:
import {
Init,
HandleCallback,
} from "@edvizion/auth";
await Init(
"YOUR_CLIENT_ID",
"https://your-app.com/auth/callback",
"https://your-auth.authkit.app",
);
await HandleCallback();
window.location.replace("/");Reading the authenticated identity
Edvizion Auth exposes identity information separately from OAuth credentials:
import { Identity } from "@edvizion/auth";Get the complete identity:
const user = await Identity.get();
if (user) {
console.log(user.name);
console.log(user.email);
}The returned object has the shape:
type IdentityInfo = {
id: string;
name?: string;
givenName?: string;
familyName?: string;
email?: string;
emailVerified?: boolean;
};Convenience methods are also available:
const id = await Identity.getID();
const name = await Identity.getName();
const firstName = await Identity.getFirstName();
const lastName = await Identity.getLastName();
const email = await Identity.getEmail();
const verified = await Identity.isEmailVerified();When applicable, these methods wait for an in-progress identity validation before returning.
If no user is authenticated, nullable values return null.
Reacting to identity changes
The identity store is framework-independent.
Subscribe to changes:
const unsubscribe = Identity.subscribe((identity) => {
if (identity) {
console.log(`Signed in as ${identity.name}`);
} else {
console.log("Not signed in");
}
});Stop listening when appropriate:
unsubscribe();This can be integrated with Lit, React, Vue, vanilla JavaScript, or any other frontend framework.
For example, a Lit component can request an update whenever identity changes:
connectedCallback() {
super.connectedCallback();
this.unsubscribeIdentity = Identity.subscribe(() => {
this.requestUpdate();
});
}
disconnectedCallback() {
this.unsubscribeIdentity?.();
super.disconnectedCallback();
}Then render normally:
const name = await Identity.getName();Full-page navigation
Sessions persist across ordinary browser navigations.
For example:
/dashboard
↓
/students
↓
/students/123Each new page initializes Edvizion Auth.
The SDK restores the cached session from browser storage and refreshes the access token when necessary.
Application code does not need to manually preserve authentication between pages.
Identity caching
Identity information is cached locally so applications can restore user-facing information without unnecessarily requesting it on every page load.
The cached identity is refreshed when OAuth tokens are issued or refreshed.
If no usable authentication session exists, the identity cache is cleared.
The identity cache is intended for presentation such as:
- User name
- Email address
- Account/avatar UI
- Signed-in state
Do not use frontend identity information to make security or authorization decisions.
Permissions and access control must be enforced by the server using the authenticated request.
Token storage
OAuth session credentials are managed internally by Edvizion Auth.
Consumers should not:
localStorage.getItem("edvizion_auth:...");or attempt to manually read, update, refresh, or attach tokens.
Use:
fetch(...)for authenticated requests and:
Identityfor user-facing identity information.
Typical application entrypoint
import { Init } from "@edvizion/auth";
Init(
"client_...",
"https://recreq.com/auth/callback",
"https://your-auth.authkit.app",
);
await import("./app");Application code can then simply do:
import { Identity } from "@edvizion/auth";
const user = await Identity.get();
const response = await fetch("/api/dashboard");Authentication, session restoration, token refresh, and request authorization are handled automatically.
