feat(auth): Make token auth default (#6305)

**What**
- make token auth the default being returned from authentication endpoints in api-v2
- Add `auth/session` to convert token to session based auth
- add regex-scopes to authenticate middleware 

Co-authored-by: Sebastian Rindom <7554214+srindom@users.noreply.github.com>
This commit is contained in:
Philip Korsholm
2024-02-05 08:17:08 +00:00
committed by GitHub
co-authored by Sebastian Rindom
parent 96ba49329b
commit e2738ab91d
21 changed files with 147 additions and 138 deletions
@@ -1,8 +1,8 @@
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
import jwt from "jsonwebtoken"
import { MedusaError } from "@medusajs/utils"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
import { MedusaRequest, MedusaResponse } from "../../../../../types/routing"
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const { scope, authProvider } = req.params
@@ -29,10 +29,9 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
}
if (success) {
req.session.auth_user = authUser
req.session.scope = authUser.scope
return res.status(200).json({ authUser })
const { jwt_secret } = req.scope.resolve("configModule").projectConfig
const token = jwt.sign(authUser, jwt_secret)
return res.status(200).json({ token })
}
throw new MedusaError(
@@ -1,8 +1,8 @@
import jwt from "jsonwebtoken"
import { AuthenticationInput, IAuthModuleService } from "@medusajs/types"
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
import { MedusaError } from "@medusajs/utils"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const { scope, authProvider } = req.params
@@ -29,10 +29,11 @@ export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
}
if (success) {
req.session.auth_user = authUser
req.session.scope = authUser.scope
const { jwt_secret } = req.scope.resolve("configModule").projectConfig
return res.status(200).json({ authUser })
const token = jwt.sign(authUser, jwt_secret)
return res.status(200).json({ token })
}
throw new MedusaError(
@@ -0,0 +1,10 @@
import { MiddlewareRoute } from "../../types/middlewares"
import { authenticate } from "../../utils/authenticate-middleware"
export const authRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["POST"],
matcher: "/auth/session",
middlewares: [authenticate(/.*/, "bearer")],
},
]
@@ -0,0 +1,7 @@
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
req.session.auth_user = req.auth_user
res.status(200).json({ user: req.auth_user })
}
@@ -5,6 +5,7 @@ import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
import { authRoutesMiddlewares } from "./auth/middlewares"
export const config: MiddlewaresConfig = {
routes: [
@@ -14,5 +15,6 @@ export const config: MiddlewaresConfig = {
...adminCampaignRoutesMiddlewares,
...storeCustomerRoutesMiddlewares,
...storeCartRoutesMiddlewares,
...authRoutesMiddlewares,
],
}
+2
View File
@@ -228,9 +228,11 @@ class InviteService extends TransactionBaseService {
verifyToken(token): JwtPayload | string {
const { jwt_secret } = this.configModule_.projectConfig
if (jwt_secret) {
return jwt.verify(token, jwt_secret)
}
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Please configure jwt_secret"
-2
View File
@@ -1,7 +1,5 @@
import type { Customer, User } from "../models"
import type { NextFunction, Request, Response } from "express"
import { AuthUserDTO } from "@medusajs/types"
import type { MedusaContainer } from "./global"
export interface MedusaRequest extends Request {
@@ -1,8 +1,9 @@
import { AuthUserDTO, IAuthModuleService } from "@medusajs/types"
import { MedusaRequest, MedusaResponse } from "../types/routing"
import { NextFunction, RequestHandler } from "express"
import jwt, { JwtPayload } from "jsonwebtoken"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { AuthUserDTO } from "@medusajs/types"
import { stringEqualsOrRegexMatch } from "@medusajs/utils"
const SESSION_AUTH = "session"
const BEARER_AUTH = "bearer"
@@ -15,7 +16,7 @@ type MedusaSession = {
type AuthType = "session" | "bearer"
export const authenticate = (
authScope: string,
authScope: string | RegExp,
authType: AuthType | AuthType[],
options: { allowUnauthenticated?: boolean } = {}
): RequestHandler => {
@@ -25,22 +26,23 @@ export const authenticate = (
next: NextFunction
): Promise<void> => {
const authTypes = Array.isArray(authType) ? authType : [authType]
const authModule = req.scope.resolve<IAuthModuleService>(
ModuleRegistrationName.AUTH
)
// @ts-ignore
const session: MedusaSession = req.session || {}
let authUser: AuthUserDTO | null = null
if (authTypes.includes(SESSION_AUTH)) {
if (session.auth_user && session.scope === authScope) {
if (
session.auth_user &&
stringEqualsOrRegexMatch(authScope, session.auth_user.scope)
) {
authUser = session.auth_user
}
}
if (!authUser && authTypes.includes(BEARER_AUTH)) {
const authHeader = req.headers.authorization
if (authHeader) {
const re = /(\S+)\s+(\S+)/
const matches = authHeader.match(re)
@@ -49,10 +51,17 @@ export const authenticate = (
if (matches) {
const tokenType = matches[1]
const token = matches[2]
if (tokenType.toLowerCase() === "bearer") {
authUser = await authModule
.retrieveAuthUserFromJwtToken(token, authScope)
.catch(() => null)
if (tokenType.toLowerCase() === BEARER_AUTH) {
// get config jwt secret
// verify token and set authUser
const { jwt_secret } =
req.scope.resolve("configModule").projectConfig
const verified = jwt.verify(token, jwt_secret) as JwtPayload
if (stringEqualsOrRegexMatch(authScope, verified.scope)) {
authUser = verified as AuthUserDTO
}
}
}
}
@@ -62,7 +71,7 @@ export const authenticate = (
req.auth_user = {
id: authUser.id,
app_metadata: authUser.app_metadata,
scope: authScope,
scope: authUser.scope,
}
return next()
}