Example: Access Logged-In User
This document gives an example of how you can use middlewares 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.
You can apply the same steps if you want to register the current customer.
Learn more about middlewares in its guide.
Step 1: Create the Middleware
Create the file src/api/middlewares.ts
with the following content:
import type {
authenticate,
MiddlewaresConfig,
User,
UserService,
} from "@medusajs/medusa"
import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
const registerLoggedInUser = async (
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) => {
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()
}
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/admin/products",
middlewares: [authenticate(), registerLoggedInUser],
},
],
}
This creates a registerLoggedInUser
middleware that handles registering the logged-in user in the dependency container.
It then applies this middleware on the /admin/products
API Route. You can change that to be the route of any other API Route or a pattern that matches multiple routes.
Step 2: Use in a Service
Access the logged-in user resource in the constructor of a service:
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:
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.
Step 3: Test it Out
To test out your implementation, run the following command in the root directory of the Medusa backend to transpile your changes:
Then, run your backend with the following command:
If you try accessing the API Routes you added the middleware to, you should see your implementation working as expected.