- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
How to Create an Auth Provider Module
In this document, you’ll learn how to create an auth provider module and the methods you must implement in its main service.
1. Create Module Directory#
Start by creating a new directory for your module. For example, src/modules/my-auth
.
2. Create the Auth Provider Service#
Create the file src/modules/my-auth/service.ts
that holds the module's main service. It must extend the AbstractAuthModuleProvider
class imported from @medusajs/framework/utils
:
constructor#
The constructor allows you to access resources from the module's container using the first parameter, and the module's options using the second parameter.
If you're creating a client or establishing a connection with a third-party service, do it in the constructor.
Example
1import { AbstractAuthModuleProvider } from "@medusajs/framework/utils"2import { Logger } from "@medusajs/framework/types"3 4type InjectedDependencies = {5 logger: Logger6}7 8type Options = {9 apiKey: string10}11 12class MyAuthProviderService extends AbstractAuthModuleProvider {13 static identifier = "my-auth"14 protected logger_: Logger15 protected options_: Options16 // assuming you're initializing a client17 protected client18 19 constructor (20 { logger }: InjectedDependencies,21 options: Options22 ) {23 super(...arguments)24 25 this.logger_ = logger26 this.options_ = options27 28 // assuming you're initializing a client29 this.client = new Client(options)30 }31 32 // ...33}34 35export default MyAuthProviderService
constructor#
validateOptions#
This method validates the options of the provider set in medusa-config.ts
.
Implementing this method is optional. It's useful if your provider requires custom validation.
If the options aren't valid, throw an error.
Example
Parameters
options
Record<any, any>Returns
void
voidmedusa-config.ts
.
Implementing this method is optional. It's useful if your provider requires custom validation.
If the options aren't valid, throw an error.authenticate#
This method authenticates the user.
The authentication happens either by directly authenticating or returning a redirect URL to continue the authentication with a third party provider.
Related Read: Learn about the different authentication flows in Medusa.
Example
For example, if your authentication provider doesn't require validating a callback:
1import {2 AuthIdentityProviderService,3 AuthenticationInput,4 AuthenticationResponse5} from "@medusajs/framework/types"6// ...7 8class MyAuthProviderService extends AbstractAuthModuleProvider {9 // ...10 async authenticate(11 data: AuthenticationInput,12 authIdentityProviderService: AuthIdentityProviderService13 ): Promise<AuthenticationResponse> {14 const isAuthenticated = false15 // TODO perform custom logic to authenticate the user16 // for example, verifying a password17 18 if (!isAuthenticated) {19 // if the authentication didn't succeed, return20 // an object of the following format21 return {22 success: false,23 error: "Incorrect credentials"24 }25 }26 27 // authentication is successful, retrieve the identity28 const authIdentity = await authIdentityProviderService.retrieve({29 entity_id: data.body.email, // email or some ID30 provider: this.provider31 })32 33 return {34 success: true,35 authIdentity36 }37 }38}
If your authentication provider requires validating callback:
1import {2 AuthIdentityProviderService,3 AuthenticationInput,4 AuthenticationResponse5} from "@medusajs/framework/types"6// ...7 8class MyAuthProviderService extends AbstractAuthModuleProvider {9 // ...10 async authenticate(11 data: AuthenticationInput,12 authIdentityProviderService: AuthIdentityProviderService13 ): Promise<AuthenticationResponse> {14 const isAuthenticated = false15 // TODO perform custom logic to authenticate the user16 // ...17 18 if (!isAuthenticated) {19 // if the authentication didn't succeed, return20 // an object of the following format21 return {22 success: false,23 error: "Incorrect credentials"24 }25 }26 27 return {28 success: true,29 location: "some-url.com"30 }31 }32}
Parameters
The details of the authentication request.
authIdentityProviderService
AuthIdentityProviderServicecreate
to create an auth identity,
and retrieve
to retrieve an auth identity. When you authenticate the user, you can create an auth identity
using this service.Returns
Promise
Promise<AuthenticationResponse>The authentication response.
Promise
Promise<AuthenticationResponse>register#
This method receives credentails to create a new auth identity. It performs any validation necessary before creating the auth identity.
For example, in the emailpass
provider, this method ensures that the provided email doesn't exist
before creating the auth identity.
This method is only used in a basic authentication flow, such as when using an email and password to register and authenticate a user.
Related Read: Learn about the different authentication flows in Medusa.
Example
1import {2 AuthIdentityProviderService,3 AuthenticationInput,4 AuthenticationResponse5} from "@medusajs/framework/types"6import { MedusaError } from "@medusajs/framework/utils"7// ...8 9class MyAuthProviderService extends AbstractAuthModuleProvider {10 // ...11 async register(12 data: AuthenticationInput,13 authIdentityProviderService: AuthIdentityProviderService14 ): Promise<AuthenticationResponse> {15 try {16 await authIdentityService.retrieve({17 entity_id: data.body.email, // email or some ID18 })19 20 return {21 success: false,22 error: "Identity with email already exists",23 }24 } catch (error) {25 if (error.type === MedusaError.Types.NOT_FOUND) {26 const createdAuthIdentity = await authIdentityProviderService.create({27 entity_id: data.body.email, // email or some ID28 provider: this.provider,29 provider_metadata: {30 // can include password or any other relevant information31 }32 })33 34 return {35 success: true,36 authIdentity: createdAuthIdentity,37 }38 }39 40 return { success: false, error: error.message }41 }42 }43}
Parameters
The details of the authentication request.
authIdentityProviderService
AuthIdentityProviderServicecreate
to create an auth identity,
and retrieve
to retrieve an auth identity. When you authenticate the user, you can create an auth identity
using this service.Returns
Promise
Promise<AuthenticationResponse>The created authentication identity if no errors occur.
Promise
Promise<AuthenticationResponse>update#
This method is used to update an auth identity's details.
For example, the emailpass
provider's implementation of this method updates a user's password.
Example
1import {2 AuthIdentityProviderService,3 AuthenticationInput,4 AuthenticationResponse5} from "@medusajs/framework/types"6import { MedusaError } from "@medusajs/framework/utils"7// ...8 9class MyAuthProviderService extends AbstractAuthModuleProvider {10 // ...11 async update(12 data: Record<string, unknown>,13 authIdentityProviderService: AuthIdentityProviderService14 ): Promise<AuthenticationResponse> {15 try {16 const authIdentity = await authIdentityService.update(17 data.email, // email or some ID used to identify the auth identity18 {19 user: data.user // example20 }21 )22 23 return { success: true, authIdentity }24 } catch (error) {25 return { success: false, error: error.message }26 }27 }28}
Parameters
data
Record<string, unknown>emailpass
provider expects in this object an email
and password
properties.authIdentityProviderService
AuthIdentityProviderServicecreate
to create an auth identity,
and retrieve
to retrieve an auth identity. When you authenticate the user, you can create an auth identity
using this service.Returns
Promise
Promise<AuthenticationResponse>The updated authentication identity if no errors occur.
Promise
Promise<AuthenticationResponse>validateCallback#
This method validates the callback of an authentication request.
In an authentication flow that requires performing an action with a third-party service, such as login with a social account, the authenticate method is called first.
Then, the third-party service redirects to a frontend URL passing it a code
query parameter.
The frontend should then send a request to the Medusa application's validate callback API route, passing it the code.
That route uses this method to verify the callback's code.
If the callback is verified successfully, the provider creates an auth identity for the user, or updates the auth identity's user information.
In the auth identity, use the following properties to store additional data:
provider_metadata
: Store metadata useful for the provider, such as a password hash.user_metadata
: Store metadata of the user's details. For example, if the third-party service returns the user's information such as email or name, you store this data in this property.
Related Guide: Learn about the different authentication flows in Medusa.
Example
1import {2 AuthIdentityProviderService,3 AuthenticationInput,4 AuthenticationResponse5} from "@medusajs/framework/types"6// ...7 8class MyAuthProviderService extends AbstractAuthModuleProvider {9 // ...10 async validateCallback(11 data: AuthenticationInput,12 authIdentityProviderService: AuthIdentityProviderService13 ): Promise<AuthenticationResponse> {14 const isAuthenticated = false15 // TODO perform custom logic to authenticate the user16 // ...17 18 if (!isAuthenticated) {19 // if the authentication didn't succeed, return20 // an object of the following format21 return {22 success: false,23 error: "Something went wrong"24 }25 }26 27 // authentication is successful, create an auth identity28 // if doesn't exist29 let authIdentity30 31 try {32 authIdentity = await authIdentityProviderService.retrieve({33 entity_id: data.body.email, // email or some ID34 provider: this.provider35 })36 } catch (e) {37 // The auth identity doesn't exist so create it38 authIdentity = await authIdentityProviderService.create({39 entity_id: data.body.email, // email or some ID40 provider: this.provider,41 provider_metadata: {42 // can include password or any other relevant information43 },44 user_metadata: {45 // can include data retrieved from the third-party service46 }47 })48 }49 50 return {51 success: true,52 authIdentity53 }54 }55}
Parameters
The details of the authentication request.
authIdentityProviderService
AuthIdentityProviderServicecreate
to create an auth identity,
and retrieve
to retrieve an auth identity. When you authenticate the user, you can create an auth identity
using this service.Returns
Promise
Promise<AuthenticationResponse>The authentication response.
Promise
Promise<AuthenticationResponse>3. Create Module Definition File#
Create the file src/modules/my-auth/index.ts
with the following content:
This exports the module's definition, indicating that the MyAuthProviderService
is the module's service.
4. Use Module#
To use your Auth Module Provider, add it to the providers
array of the Auth Module in medusa-config.ts
:
1import { Modules } from "@medusajs/framework/utils"2 3// ...4 5module.exports = defineConfig({6 // ...7 modules: [8 {9 resolve: "@medusajs/medusa/auth",10 options: {11 providers: [12 {13 resolve: "./src/modules/my-auth",14 id: "my-auth",15 options: {16 // provider options...17 },18 },19 ],20 },21 },22 ]23})
5. Test it Out#
To test out your authentication provider, use any of the Authentication Routes, using your provider's ID as a path parameter.
For example, to get a registration token for an admin user, send a POST
request to /auth/user/my-auth/register
replacing my-auth
with your authentication provider's ID:
Change the request body to pass the data required for your authentication provider to register the user.
If registration is successful, the response will have a token
property.