* initialized next.js project * finished markdown sections * added operation schema component * change page metadata * eslint fixes * fixes related to deployment * added response schema * resolve max stack issue * support for different property types * added support for property types * added loading for components * added more loading * type fixes * added oneOf type * removed console * fix replace with push * refactored everything * use static content for description * fixes and improvements * added code examples section * fix path name * optimizations * fixed tag navigation * add support for admin and store references * general enhancements * optimizations and fixes * fixes and enhancements * added search bar * loading enhancements * added loading * added code blocks * added margin top * add empty response text * fixed oneOf parameters * added path and query parameters * general fixes * added base path env variable * small fix for arrays * enhancements * design enhancements * general enhancements * fix isRequired * added enum values * enhancements * general fixes * general fixes * changed oas generation script * additions to the introduction section * added copy button for code + other enhancements * fix response code block * fix metadata * formatted store introduction * move sidebar logic to Tags component * added test env variables * fix code block bug * added loading animation * added expand param + loading * enhance operation loading * made responsive + improvements * added loading provider * fixed loading * adjustments for small devices * added sidebar label for endpoints * added feedback component * fixed analytics * general fixes * listen to scroll for other headings * added sample env file * update api ref files + support new fields * fix for external docs link * added new sections * fix last item in sidebar not showing * move docs content to www/docs * change redirect url * revert change * resolve build errors * configure rewrites * changed to environment variable url * revert changing environment variable name * add environment variable for API path * fix links * fix tailwind settings * remove vercel file * reconfigured api route * move api page under api * fix page metadata * fix external link in navigation bar * update api spec * updated api specs * fixed google lint error * add max-height on request samples * add padding before loading * fix for one of name * fix undefined types * general fixes * remove response schema example * redesigned navigation bar * redesigned sidebar * fixed up paddings * added feedback component + report issue * fixed up typography, padding, and general styling * redesigned code blocks * optimization * added error timeout * fixes * added indexing with algolia + fixes * fix errors with algolia script * redesign operation sections * fix heading scroll * design fixes * fix padding * fix padding + scroll issues * fix scroll issues * improve scroll performance * fixes for safari * optimization and fixes * fixes to docs + details animation * padding fixes for code block * added tab animation * fixed incorrect link * added selection styling * fix lint errors * redesigned details component * added detailed feedback form * api reference fixes * fix tabs * upgrade + fixes * updated documentation links * optimizations to sidebar items * fix spacing in sidebar item * optimizations and fixes * fix endpoint path styling * remove margin * final fixes * change margin on small devices * generated OAS * fixes for mobile * added feedback modal * optimize dark mode button * fixed color mode useeffect * minimize dom size * use new style system * radius and spacing design system * design fixes * fix eslint errors * added meta files * change cron schedule * fix docusaurus configurations * added operating system to feedback data * change content directory name * fixes to contribution guidelines * revert renaming content * added api-reference to documentation workflow * fixes for search * added dark mode + fixes * oas fixes * handle bugs * added code examples for clients * changed tooltip text * change authentication to card * change page title based on selected section * redesigned mobile navbar * fix icon colors * fix key colors * fix medusa-js installation command * change external regex in algolia * change changeset * fix padding on mobile * fix hydration error * update depedencies
221 lines
6.3 KiB
Plaintext
221 lines
6.3 KiB
Plaintext
---
|
||
description: 'In this document, you’ll see an example of how you can use middlewares and endpoints to register the logged-in user in the dependency container of your commerce application.'
|
||
addHowToData: true
|
||
---
|
||
|
||
import Troubleshooting from '@site/src/components/Troubleshooting'
|
||
import ServiceLifetimeSection from '../../troubleshooting/awilix-resolution-error/_service-lifetime.md'
|
||
import CustomRegistrationSection from '../../troubleshooting/awilix-resolution-error/_custom-registration.md'
|
||
|
||
# Example: Access Logged-In User
|
||
|
||
In this document, you’ll see an example of how you can use middlewares and endpoints to register the logged-in user in the dependency container of your commerce application. You can then access the logged-in user in other resources, such as services.
|
||
|
||
This guide showcases how to register the logged-in admin user, but you can apply the same steps if you want to register the current customer.
|
||
|
||
This documentation does not explain the basics of [middlewares](./add-middleware.mdx) and [endpoints](./create.mdx). You can refer to their respective guides for more details about each.
|
||
|
||
## Step 1: Create the Middleware
|
||
|
||
Create the file `src/api/middlewares/logged-in-user.ts` with the following content:
|
||
|
||
```ts title=src/api/middlewares/logged-in-user.ts
|
||
import { User, UserService } from "@medusajs/medusa"
|
||
|
||
export async function registerLoggedInUser(req, res, next) {
|
||
let loggedInUser: User | null = null
|
||
|
||
if (req.user && req.user.userId) {
|
||
const userService =
|
||
req.scope.resolve("userService") as UserService
|
||
loggedInUser = await userService.retrieve(req.user.userId)
|
||
}
|
||
|
||
req.scope.register({
|
||
loggedInUser: {
|
||
resolve: () => loggedInUser,
|
||
},
|
||
})
|
||
|
||
next()
|
||
}
|
||
```
|
||
|
||
This retrieves the ID of the current user to retrieve an instance of it, then registers it in the scope under the name `loggedInUser`.
|
||
|
||
---
|
||
|
||
## Step 2: Apply Middleware on Endpoint
|
||
|
||
If you don't have the `cors` package installed, make sure to install it first:
|
||
|
||
```bash npm2yarn
|
||
npm install cors
|
||
```
|
||
|
||
Then, create the file `src/api/routes/create-product.ts` with the following content:
|
||
|
||
```ts title=src/api/routes/create-product.ts
|
||
import cors from "cors"
|
||
import { Router } from "express"
|
||
import {
|
||
registerLoggedInUser,
|
||
} from "../middlewares/logged-in-user"
|
||
import
|
||
authenticate
|
||
from "@medusajs/medusa/dist/api/middlewares/authenticate"
|
||
|
||
const router = Router()
|
||
|
||
export default function (adminCorsOptions) {
|
||
// This router will be applied before the core routes.
|
||
// Therefore, the middleware will be executed
|
||
// before the create product handler is hit
|
||
router.use(
|
||
"/admin/products",
|
||
cors(adminCorsOptions),
|
||
authenticate(),
|
||
registerLoggedInUser
|
||
)
|
||
return router
|
||
}
|
||
```
|
||
|
||
In the example above, the middleware is applied on the `/admin/products` core endpoint. However, you can apply it on any other endpoint. You can also apply it to custom endpoints.
|
||
|
||
For endpoints that require Cross-Origin Resource Origin (CORS) options, such as core endpoints, you must pass the CORS options to the middleware as well since it will be executed before the underlying endpoint.
|
||
|
||
:::tip
|
||
|
||
In the above code snippet, the `authenticate` middleware imported from `@medusajs/medusa` is used to ensure that the user is logged in first. If you're implementing this for middleware to register the logged-in customer, make sure to use the [customer's authenticate middleware](./create.mdx#protect-store-routes).
|
||
|
||
:::
|
||
|
||
---
|
||
|
||
## Step 3: Register Endpoint in the API
|
||
|
||
Create the file `src/api/index.ts` with the following content:
|
||
|
||
```ts title=src/api/index.ts
|
||
import configLoader from "@medusajs/medusa/dist/loaders/config"
|
||
import createProductRouter from "./routes/create-product"
|
||
|
||
export default function (rootDirectory: string) {
|
||
const config = configLoader(rootDirectory)
|
||
|
||
const adminCors = {
|
||
origin: config.projectConfig.admin_cors.split(","),
|
||
credentials: true,
|
||
}
|
||
|
||
const productRouters = [
|
||
createProductRouter(adminCors),
|
||
]
|
||
|
||
return [...productRouters]
|
||
}
|
||
```
|
||
|
||
This exports an array of endpoints, one of them being the product endpoint that you applied the middleware on in the second step. You can export more endpoints as well.
|
||
|
||
---
|
||
|
||
## Step 4: Use in a Service
|
||
|
||
You can now access the logged-in user in a service. For example, to access it in a custom service:
|
||
|
||
<!-- eslint-disable prefer-rest-params -->
|
||
|
||
```ts
|
||
import { Lifetime } from "awilix"
|
||
import {
|
||
TransactionBaseService,
|
||
User,
|
||
} from "@medusajs/medusa"
|
||
|
||
class HelloService extends TransactionBaseService {
|
||
|
||
protected readonly loggedInUser_: User | null
|
||
|
||
constructor(container, options) {
|
||
super(...arguments)
|
||
|
||
try {
|
||
this.loggedInUser_ = container.loggedInUser
|
||
} catch (e) {
|
||
// avoid errors when backend first runs
|
||
}
|
||
}
|
||
|
||
// ...
|
||
}
|
||
|
||
export default HelloService
|
||
```
|
||
|
||
If you're accessing it in an extended core service, it’s important to change the lifetime of the service to `Lifetime.SCOPED`. For example:
|
||
|
||
<!-- eslint-disable prefer-rest-params -->
|
||
|
||
```ts
|
||
import { Lifetime } from "awilix"
|
||
import {
|
||
ProductService as MedusaProductService,
|
||
User,
|
||
} from "@medusajs/medusa"
|
||
|
||
// extend core product service
|
||
class ProductService extends MedusaProductService {
|
||
// The default life time for a core service is SINGLETON
|
||
static LIFE_TIME = Lifetime.SCOPED
|
||
|
||
protected readonly loggedInUser_: User | null
|
||
|
||
constructor(container, options) {
|
||
super(...arguments)
|
||
|
||
this.loggedInUser_ = container.loggedInUser
|
||
}
|
||
}
|
||
|
||
export default ProductService
|
||
```
|
||
|
||
You can learn more about the importance of changing the service lifetime in the [Middlewares documentation](./add-middleware.mdx#note-about-services-lifetime).
|
||
|
||
---
|
||
|
||
## Step 5: Test it Out
|
||
|
||
To test out your implementation, run the following command in the root directory of the Medusa backend to transpile your changes:
|
||
|
||
```bash npm2yarn
|
||
npm run build
|
||
```
|
||
|
||
Then, run your backend with the following command:
|
||
|
||
```bash npm2yarn
|
||
npx medusa develop
|
||
```
|
||
|
||
If you try accessing the endpoints you added the middleware to, you should see your implementation working as expected.
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
<Troubleshooting
|
||
sections={[
|
||
{
|
||
title: 'AwilixResolutionError: Could Not Resolve X',
|
||
content: <ServiceLifetimeSection />
|
||
},
|
||
{
|
||
title: 'AwilixResolutionError: Could Not Resolve X (Custom Registration)',
|
||
content: <CustomRegistrationSection />
|
||
}
|
||
]}
|
||
/>
|