Authentication
TaskOn Widget React does not replace your product login system. You only need to bridge host auth state to TaskOn auth state.
loginRequired in Widget React
In Widget React, the auth-required signal is exposed through TaskOnProvider config.onRequestLogin.
When a guest user clicks an authenticated action, this callback is triggered.
import { TaskOnProvider } from "@taskon/widget-react/core";
<TaskOnProvider
config={{
clientId: "YOUR_CLIENT_ID",
onRequestLogin: () => {
// loginRequired happens here: open your host login modal or redirect
openLoginModal();
},
}}
>
{children}
</TaskOnProvider>Complete Demo (loginRequired + login + logout)
App.tsx
import { useEffect } from "react";
import { TaskOnProvider, useTaskOnAuth } from "@taskon/widget-react/core";
import { QuestWidget } from "@taskon/widget-react/quest";
type HostUser = { email: string } | null;
async function fetchTaskOnSign(email: string): Promise<{ sign: string; timestamp: number }> {
// Call your backend signing endpoint and return { sign, timestamp }.
// Example request body:
// { "type": "Email", "value": email }
return { sign: "SERVER_SIGN", timestamp: Date.now() };
}
function TaskOnAuthBridge({ hostUser }: { hostUser: HostUser }) {
const { login, logout, isLoggedIn } = useTaskOnAuth();
useEffect(() => {
// Host login -> call login(...)
if (!hostUser || isLoggedIn) return;
void (async () => {
const signed = await fetchTaskOnSign(hostUser.email);
await login({
method: "email",
value: hostUser.email,
sign: signed.sign,
timestamp: signed.timestamp,
});
})();
}, [hostUser, isLoggedIn, login]);
useEffect(() => {
// Host logout -> call logout()
if (!hostUser && isLoggedIn) {
logout();
}
}, [hostUser, isLoggedIn, logout]);
return null;
}
function App() {
const hostUser = useHostUser(); // your own auth state
return (
<TaskOnProvider
config={{
clientId: "YOUR_CLIENT_ID",
onRequestLogin: () => {
// Widget asks for auth (loginRequired path)
openLoginModal();
},
}}
>
<TaskOnAuthBridge hostUser={hostUser} />
<QuestWidget widgetId={98765} />
</TaskOnProvider>
);
}Call Timing Summary
onRequestLogin: user clicks an authenticated action while not logged in.login(...): your host login succeeds and backend returnssign+timestamp.logout(): your host user logs out or session expires.
Server Signature Contract (Language-Agnostic)
You can implement signing in any backend language (Node.js, Java, Go, Python, Rust, etc.).
Required Inputs
clientId: your TaskOn client idtype:"Email"or"evm"value: email or EVM wallet addressprivateKey: TaskOn private key (Base64-encoded PKCS#1 DER)
Required Output
sign: Base64 signature stringtimestamp: Unix timestamp in milliseconds (13 digits)
Signing Rules
- Build message:
${type}|${value}|${clientId}|${timestamp} - Sign message bytes with
RSA-SHA256and PKCS#1 private key - Base64-encode signature bytes as
sign - Return the same
timestampused in the message - Pass
signandtimestampdirectly tologin(...)(do not convert timestamp to seconds)
Node.js Signing Logic (raw implementation)
import { createSign } from "crypto";
export function createTaskOnSign(params: {
clientId: string;
type: "Email" | "evm";
value: string;
privateKeyBase64: string;
}) {
// 1) Keep the original 13-digit millisecond timestamp
const timestamp = Date.now();
// 2) Build message in TaskOn-required format
const message = `${params.type}|${params.value}|${params.clientId}|${timestamp}`;
// 3) Decode Base64 PKCS#1 private key (DER bytes)
const privateKeyBuffer = Buffer.from(params.privateKeyBase64, "base64");
// 4) Sign with RSA-SHA256
const signer = createSign("RSA-SHA256");
signer.update(message);
const signature = signer.sign({
key: privateKeyBuffer,
format: "der",
type: "pkcs1",
});
// 5) Return Base64 signature + same timestamp
return {
sign: signature.toString("base64"),
timestamp,
};
}On Node.js servers, you can directly call signMessage(...) provided by @taskon/core.
Login Method Mapping
| Widget login method | value |
|---|---|
email | user email |
evm_wallet | EVM address |
discord | OAuth token |
twitter | OAuth token |
telegram | OAuth token |
Security Notes
- Keep
TASKON_PRIVATE_KEYon server only. - Never generate TaskOn sign in frontend production code.
- Keep one source of truth for auth state (host auth -> sync to TaskOn).
Last updated on