Authorization: UI Elements
Using session data in pages
It's important to note that the WithWine SDK is designed to be used in a server side context, this means that you can't use the SDK in the browser to fetch data from the WithWine API. If you need to fetch data from the WithWine API in the browser you will need to create the appropriate API routes to do so. See below for an example of this.
At some point you will want to access user data from the WithWine API in your
pages, you can implement the withWineSessionMiddleware
middleware in an API
route, then you can access user data when fetching from the
WithWine API by supplying the appropriate headers in your fetch. To make this as
simple as possible we've included a withWineFetchHeaders
method that will do
this for you in a secure manner. You can spread the result of this method onto
the headers
object that you pass into your fetch.
import { WITHWINE_SETTINGS, withWineFetchHeaders } from '@withwine/sdk';
import { withWineSessionMiddleware } from '@withwine/sdk/nuxt';
/**
* Example of Nuxt defineEventHandler using the `withWineSessionMiddleware`
* middleware. The fetch in this method uses the WithWine SDK
* `withWineFetchHeaders` method to get the headers required to make requests to
* the WithWine API.
*/
export default defineEventHandler(async (event) => {
const wwEvent = await withWineSessionMiddleware(event);
const { req } = wwEvent.node;
const { apiBaseUrl } = WITHWINE_SETTINGS;
const response = await fetch(`${apiBaseUrl}api/wine/product?id=${event?.context?.params?.id}`, {
headers: {
...withWineFetchHeaders(req),
},
});
return await response.json();
});
Considering the above API route is now set up you can create a Product page in
the pages directory and using the useFetch
composable, fetch the product data
from the WithWine API, the fecth will include any user data in the request. The
below example assumes that you have a product page like the following:
https://your-domain.com/product/1234
.
<script setup lang="ts">
const route = useRoute();
const { data } = await useFetch(`/api/withwine/product/${route.params.id}`);
const product = data.value;
</script>
<template>
<div>
<h1>Product API Request test page</h1>
<pre v-if="product">{{ product }}</pre>
<pre v-if="!product">No product Loaded...</pre>
</div>
</template>
Accessing user data with the useUser composable
The WithWine SDK exposes a useUser
composable that can be added to the client side
code where you wish to access the state of the user, i.e. see if the user is
logged in, get the user name etc.. This composable calls the
/api/withwine/user
API route.
Under the hood the useUser
composable uses Nuxt's
useFetch composable
but you must pass this into the useUser
composable when you call it. The
useUser
composable returns a user
object.
- Using direct API calls
- Using Redirects
<script setup lang="ts">
import { useUser } from '@withwine/sdk/nuxt-client';
import type { User } from '@withwine/sdk/types';
const { data } = await useAsyncData('user', async () => await useUser({ useFetch }));
const user: User | null = data.value;
</script>
<template>
<div>
<ul>
<li v-if="!user?.isLoggedIn"><a href="/api/withwine/login">Login</a></li>
<li v-if="!user?.isLoggedIn"><a href="/api/withwine/register">Register</a></li>
<li v-if="user?.isLoggedIn"><a href="/api/withwine/logout">logout {{ user.name }}</a></li>
</ul>
</div>
</template>
<script setup lang="ts">
import { useUser } from '@withwine/sdk/nuxt-client';
import type { User } from '@withwine/sdk/types';
const { data } = await useAsyncData('user', async () => await useUser({ useFetch }));
const user: User | null = data.value;
</script>
<template>
<div>
<ul>
<li v-if="!user?.isLoggedIn"><a href="/withwine/login">Login</a></li>
<li v-if="!user?.isLoggedIn"><a href="/withwine/register">Register</a></li>
<li v-if="user?.isLoggedIn"><a href="/withwine/logout">logout {{ user.name }}</a></li>
</ul>
</div>
</template>
The above samples show both direct API route access and redirect based links as
dicussed in in the previous
section on
redirects,t
he only notable difference is the omition of the /api
path in the href
attributes.