Access the protected service
If you’ve completed all of the previous steps, you should be able to:
- Connect wallet
- Select an account to sign in with
- Generate and sign a nonce
- Receive a JWT after your signature is verified
Now let’s wrap it up and use that JWT to access the protected service.
Access protected endpoint
First, let’s create a UI component that will consume the protected data. In src/components/demo/Profile.tsx
, access the protected service with the JWT we obtained:
// src/components/demo/Profile.tsx
import { useCallback } from "react"
type Props = {
jwtToken: string
}
export const Profile: React.FC<Props> = ({ jwtToken }) => {
const generate = useCallback(async (jwtToken?: string) => {
try {
const res = await fetch("/api/protected", {
headers: {
Authorisation: `Bearer ${jwtToken}`,
},
})
const data = await res.json()
if (data.error) throw new Error(data.error)
console.log(data.randomText)
} catch (e: any) {
// unauthenticated
}
}, [])
return <button onClick={() => generate(jwtToken)}>Generate Random Text</button>
}
Handle JWT
Remember in the src/components/demo/SignIn.tsx
we called onSignedIn
after a user has signed in? Let’s handle that JWT so we can access the protected API using the <Profile />
component we just created.
// src/components/demo/index.tsx
import { useCallback, useEffect, useState } from "react"
import { InjectedAccountWithMeta } from "@polkadot/extension-inject/types"
import { ConnectWallet } from "./ConnectWallet"
import { SignIn } from "./SignIn"
import { Profile } from "./Profile"
export const Demo = () => {
// ...
// create states to hold the JWT token and the signed in account
const [signedInWith, setSignedInWith] = useState<InjectedAccountWithMeta | undefined>()
const [jwtToken, setJwtToken] = useState<string | undefined>()
// called when `onSignedIn` is invoked
const handleSignedIn = (selectedAccount: InjectedAccountWithMeta, jwtToken: string) => {
setJwtToken(jwtToken)
setSignedInWith(selectedAccount)
}
useEffect(() => {
subscribeToExtensions()
}, [subscribeToExtensions])
return (
<div className="w-full">
<div className="border-stone-800 border p-4 rounded-xl w-full min-h-[384px] sm:h-96 flex flex-col flex-1">
{/* shows a page to access the protected service */}
{signedInWith && !!jwtToken ? (
<Profile jwtToken={jwtToken} />
) : accounts ? (
<SignIn
accounts={accounts}
onCancel={() => setAccounts(undefined)}
onSignedIn={handleSignedIn}
/>
) : (
<ConnectWallet onAccounts={setAccounts} />
)}
</div>
</div>
)
}
Now restart your dev server and you should be able to connect wallet, sign in, and generate random text from your backend. Check the random text in your browser console.
That’s it! We’ve built a full stack dApp that authenticates users securely with just their Substrate wallet, no third party providers required!