Methods
API reference for authentication methods available through the useDeva() hook.
Overview
The SDK provides two primary authentication methods accessed via the useDeva hook:
login()- Initiates OAuth authentication flowlogout()- Revokes tokens and clears authentication state
login()
Initiates the OAuth 2.0 + OIDC authentication flow with PKCE.
Signature
login: () => Promise<void>Usage
import { useDeva } from "@bitplanet/deva-sdk";
function LoginButton() {
const { login, isAuthenticated } = useDeva();
if (isAuthenticated) {
return null;
}
return <button onClick={login}>Login with Deva</button>;
}Behavior
When Called:
Clears any existing authentication state
Generates PKCE code verifier and challenge
Redirects browser to Deva authorization endpoint
User authenticates on Deva platform
User grants permissions to your app
Deva redirects back to your
redirectUriwith authorization codeSDK exchanges code for access and refresh tokens
SDK fetches user information
Tokens stored in sessionStorage
isAuthenticatedbecomestrue
Parameters:
None
Returns:
Promise<void>- Resolves immediately after redirect
Errors:
Throws if OpenID configuration not loaded
Network errors handled internally with retries
Example Flow
function App() {
const { login, isReady, isAuthenticated } = useDeva();
if (!isReady) {
return <div>Loading...</div>;
}
if (!isAuthenticated) {
return (
<div>
<h1>Welcome</h1>
<button onClick={login}>Sign In</button>
</div>
);
}
return <Dashboard />;
}logout()
Revokes the access token and clears all authentication state.
Signature
logout: () => Promise<void>Usage
import { useDeva } from "@bitplanet/deva-sdk";
function LogoutButton() {
const { logout, user } = useDeva();
return (
<div>
<span>Logged in as {user?.preferred_username}</span>
<button onClick={logout}>Logout</button>
</div>
);
}Behavior
When Called:
Sends revocation request to Deva OAuth server
Clears sessionStorage (access_token, refresh_token, id_token)
Resets internal authentication state
isAuthenticatedbecomesfalseuserbecomesnullaccessTokenbecomesnull
Parameters:
None
Returns:
Promise<void>- Resolves when logout complete
Errors:
Network errors logged but do not throw
Logout completes even if revocation fails
Local state always cleared
Example with Confirmation
function LogoutButton() {
const { logout } = useDeva();
const [isLoggingOut, setIsLoggingOut] = useState(false);
const handleLogout = async () => {
if (confirm("Are you sure you want to log out?")) {
setIsLoggingOut(true);
await logout();
// Redirect or show message
}
};
return (
<button onClick={handleLogout} disabled={isLoggingOut}>
{isLoggingOut ? "Logging out..." : "Logout"}
</button>
);
}Internal Methods
These methods are used internally by the SDK and not directly exposed:
refreshToken()
Purpose: Automatically refreshes expired access tokens
Behavior:
Called automatically before token expires
Checks token expiration every second via
useIntervalExchanges refresh_token for new access_token
Updates sessionStorage with new tokens
Happens transparently without user interaction
When It Runs:
Token is about to expire (checked every second)
Returns new tokens and updates state
If refresh fails, user is logged out
revokeToken()
Purpose: Revokes access token on logout
Behavior:
Called by
logout()methodSends POST request to revocation endpoint
Includes access_token and client_id
Invalidates token on server
Authentication State
Access authentication state via useDeva() hook:
const {
isAuthenticated, // true if user has valid token
isReady, // true when SDK initialized
accessToken, // current access token
user, // user information object
login, // login function
logout // logout function
} = useDeva();isAuthenticated
Type: boolean
Values:
true- User has valid access tokenfalse- User not logged in or token expired
Usage:
if (isAuthenticated) {
return <AuthenticatedContent />;
}
return <LoginPrompt />;isReady
Type: boolean
Values:
true- SDK initialization completefalse- SDK still initializing
Usage:
if (!isReady) {
return <LoadingSpinner />;
}
// SDK ready, safe to check isAuthenticatedaccessToken
Type: string | null
Value: JWT access token or null if not authenticated
Usage:
const { accessToken } = useDeva();
// Use for custom API calls
fetch("https://api.deva.me/custom", {
headers: {
Authorization: `Bearer ${accessToken}`
}
});Note: Components and hooks use this automatically. Manual use only needed for custom API calls.
Authentication Patterns
Protected Routes
function ProtectedRoute({ children }) {
const { isReady, isAuthenticated, login } = useDeva();
if (!isReady) {
return <LoadingScreen />;
}
if (!isAuthenticated) {
return (
<div>
<p>Please log in to continue</p>
<button onClick={login}>Login</button>
</div>
);
}
return <>{children}</>;
}Conditional Rendering
function App() {
const { isAuthenticated, login, logout } = useDeva();
return (
<div>
<header>
{isAuthenticated ? (
<button onClick={logout}>Logout</button>
) : (
<button onClick={login}>Login</button>
)}
</header>
<main>
{isAuthenticated ? <Dashboard /> : <LandingPage />}
</main>
</div>
);
}Automatic Redirect
function App() {
const { isReady, isAuthenticated, login } = useDeva();
useEffect(() => {
if (isReady && !isAuthenticated) {
login(); // Auto-redirect to login
}
}, [isReady, isAuthenticated, login]);
if (!isReady || !isAuthenticated) {
return <LoadingScreen />;
}
return <Dashboard />;
}Security Considerations
Token Storage:
Tokens stored in sessionStorage (not localStorage)
Cleared when browser/tab closes
Not accessible to other domains
PKCE Flow:
No client secret exposed in browser
Code verifier prevents interception attacks
State parameter prevents CSRF
Automatic Refresh:
Tokens refreshed before expiration
Seamless user experience
No re-authentication required
Best Practices:
Always use HTTPS in production
Never log tokens to console
Don't store tokens in component state
Let SDK manage token lifecycle
Related Documentation
useDeva Hook - Complete hook reference
DevaProvider - Provider configuration
OAuth Integration - OAuth flow details
Authentication Flow - How auth works
Session Persistence - Token storage
Last updated