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:
co-authored by
Sebastian Rindom
parent
96ba49329b
commit
e2738ab91d
@@ -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,
|
||||
],
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user