nuxt-auth
nuxt-auth copied to clipboard
Is there a way to make authenticated requests out of the box?
Describe the feature
I successfully managed to log in with Nuxt Auth!
Now I want to query my API from the client with a REST request using the Authentication: Bearer token
header.
I know Nuxt-Auth does this under the hood to get the context, right after logging in.
Does Nuxt Auth also provide a way to make our own authenticated requests? In the docs we have this example:
<script setup lang="ts">
const headers = useRequestHeaders(['cookie']) as HeadersInit
const { data: token } = await useFetch('/api/token', { headers })
</script>
Is this all? Is there a composable, or is this out of this library's scope? Is this the recommended way to make authenticated requests within the whole application?
Thank you
How would you implement this?
No response
Additional information
- [ ] Would you be willing to help implement this feature?
Provider
- [ ] AuthJS
- [X] Local
- [ ] Refresh
- [ ] New Provider
The docs say you have to pass the cookie explicitly for SSR, but it works without. I think Nuxt changed the default.
In the api, you can get the session or token with the composables, and you have enough to know who is making the call. Unless your API is not in the nuxt application.
@DavidDeSloovere
Unless your API is not in the nuxt application.
This is exactly the issue, I've used Nuxt Auth to sign in and get session data from an external API, but then I need to make requests like edit profile info and similar requests that need a valid token, so a composable provided by useAuth to make authenticated requests would be very helpful in such cases.
(I'm working on implementing this now but let me know if there's a better solution to this).
I store the info/token from the external system in the nuxt auth token. Every call to the external API goes to Nuxt server routes (nitro). This is to keep the API key to the external service secret.
If you want to do that, here's something to get you started:
// ./server/middleware/set-auth-context.ts
import type { Session } from "next-auth";
import type { JWT } from "next-auth/jwt";
import { getServerSession, getToken } from "#auth";
declare module "h3" {
interface H3EventContext {
authSession: Session | null;
authToken: JWT | null;
backendAccessToken: string | null;
}
}
export default defineEventHandler(async (event) => {
if (event.path.startsWith("/_")) {
return;
}
const session = await getServerSession(event);
event.context.authSession = session;
const token = await getToken({ event: event });
event.context.authToken = token;
event.context.backendAccessToken
= token?.customUserData.backendAccessToken ?? null;
});
This is using graphql codegen under the hood.
export function useExternalService(event?: H3Event | null, accessToken?: string) {
const { GRAPHQL_API_KEY } = useRuntimeConfig();
const userAccessToken = accessToken ?? event?.context.backendAccessToken;
const headers: Record<string, string> = {
apiKey: GRAPHQL_API_KEY,
};
if (userAccessToken) {
headers.Authorization = `Bearer ${userAccessToken}`;
}
const client = new GraphQLClient("https://your-external-service.com", {
headers: headers,
});
return getSdk(client, loggingWrapper);
}
I was thinking something more like this which is just a fetch method provided by useAuth composable that automatically adds Authorization header if a token exists. I can see this being more useful than manually adding token to each request, and the server middleware will add the token to each external request, but we can send requests to multiple external APIs while maybe only one of them that needs the authorization header.