Accessing protected APIs
~8 minOnce a user is signed in, calls to your own APIs need the access token attached. Pick the client you use.
Call a protected API
When your application is wrapped with `ThunderIDProvider`, you can use the `useThunderID` hook to access the authenticated `http` module. This module has the following features: - Includes the necessary authentication headers (Bearer token) - Handles token refresh when tokens expire - Provides methods like `request()` and `requestAll()` for making API calls :::tip Accessing the HTTP Client You can access the `http` client in two ways: 1. **Inside a component**: Use the `useThunderID` hook to get the `http` instance 2. **Outside a component** (e.g., in utility functions or services): Import `http` directly :::
Basic API Request
The following examples show how to use the ThunderID SDK's `http` module to call a protected API endpoint. #### Using the Hook Inside a Component
import React, { useEffect, useState } from 'react'
import { useThunderID } from '@thunderid/react'
export default function UserProfile() {
const { http, isSignedIn } = useThunderID()
const [userData, setUserData] = useState(null)
useEffect(() => {
if (!isSignedIn) {
return
}
(async () => {
try {
const response = await http.request({
url: 'https://localhost:8090/users/<user_id>',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
method: 'GET',
})
setUserData(response.data)
} catch (error) {
console.error('Error fetching user data:', error)
}
})()
}, [http, isSignedIn])
if (!isSignedIn) {
return <div>Please sign in to view your profile.</div>
}
return (
<div>
<h2>User Profile</h2>
{userData && <pre>{JSON.stringify(userData, null, 2)}</pre>}
</div>
)
}Parallel API Requests
To send multiple API requests in parallel, use the `httpRequestAll` function. It triggers parallel network requests and returns responses after all requests are completed. The following code snippet shows how to send multiple network requests in parallel:
import React, { useEffect, useState } from 'react'
import { useThunderID } from '@thunderid/react'
export default function UserProfile() {
const { http, isSignedIn } = useThunderID()
const [ userData, setUserData ] = useState({
profile: null,
applications: [],
})
useEffect(() => {
if (!isSignedIn) {
return
}
const requests = []
requests.push({
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
method: 'GET',
url: 'https://localhost:8090/users/<user_id>',
})
requests.push({
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
method: 'GET',
url: 'https://localhost:8090/applications',
})
(async () => {
try {
const response = await http.requestAll(requests)
setUserData({
profile: response[0].data,
applications: response[1].data,
})
} catch (error) {
console.error('Error fetching data:', error)
}
})()
}, [http, isSignedIn])
return <pre>{JSON.stringify(userData, null, 4)}</pre>
}Set it up
If you are not using `webWorker` as the storage type, use the `getAccessToken` function to fetch the access token. Then manually attach the token to the GraphQL client's authentication headers. :::note Storage Type Limitation This approach is not available when the storage type is set to `webWorker`. The SDK automatically manages the access token and does not expose it to the main thread. ::: The following example shows how to configure a GraphQL client with authentication using the access token:
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'
import { setContext } from '@apollo/client/link/context'
export function createAuthenticatedClient(accessToken) {
const httpLink = createHttpLink({
uri: 'https://localhost:8090/graphql',
})
const authLink = setContext((_, { headers }) => {
return {
headers: {
...headers,
authorization: accessToken ? `Bearer ${accessToken}` : '',
},
}
})
return new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache(),
})
}