Created
July 17, 2023 03:00
-
-
Save rafirh/1e3cd066062100655207e856abee713f to your computer and use it in GitHub Desktop.
- AuthException.ts in App/Exceptions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { GuardsList } from '@ioc:Adonis/Addons/Auth' | |
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' | |
import AuthException from 'App/Exceptions/AuthException' | |
/** | |
* Auth middleware is meant to restrict un-authenticated access to a given route | |
* or a group of routes. | |
* | |
* You must register this middleware inside `start/kernel.ts` file under the list | |
* of named middleware. | |
*/ | |
export default class AuthMiddleware { | |
/** | |
* The URL to redirect to when request is Unauthorized | |
*/ | |
protected redirectTo = '/login' | |
/** | |
* Authenticates the current HTTP request against a custom set of defined | |
* guards. | |
* | |
* The authentication loop stops as soon as the user is authenticated using any | |
* of the mentioned guards and that guard will be used by the rest of the code | |
* during the current request. | |
*/ | |
protected async authenticate(auth: HttpContextContract['auth'], guards: (keyof GuardsList)[]) { | |
/** | |
* Hold reference to the guard last attempted within the for loop. We pass | |
* the reference of the guard to the "AuthenticationException", so that | |
* it can decide the correct response behavior based upon the guard | |
* driver | |
*/ | |
let guardLastAttempted: string | undefined | |
for (let guard of guards) { | |
guardLastAttempted = guard | |
if (await auth.use(guard).check()) { | |
/** | |
* Instruct auth to use the given guard as the default guard for | |
* the rest of the request, since the user authenticated | |
* succeeded here | |
*/ | |
auth.defaultGuard = guard | |
return true | |
} | |
} | |
/** | |
* Unable to authenticate using any guard | |
*/ | |
throw new AuthException('Unauthorized!', 401, 'E_UNAUTHORIZED_ACCESS') | |
} | |
/** | |
* Handle request | |
*/ | |
public async handle ( | |
{ auth }: HttpContextContract, | |
next: () => Promise<void>, | |
customGuards: (keyof GuardsList)[] | |
) { | |
/** | |
* Uses the user defined guards or the default guard mentioned in | |
* the config file | |
*/ | |
const guards = customGuards.length ? customGuards : [auth.name] | |
await this.authenticate(auth, guards) | |
await next() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Exception } from '@adonisjs/core/build/standalone' | |
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' | |
/* | |
|-------------------------------------------------------------------------- | |
| Exception | |
|-------------------------------------------------------------------------- | |
| | |
| The Exception class imported from `@adonisjs/core` allows defining | |
| a status code and error code for every exception. | |
| | |
| @example | |
| new DefaultException('message', 500, 'E_RUNTIME_EXCEPTION') | |
| | |
*/ | |
export default class AuthException extends Exception { | |
public async handle(error: this, ctx: HttpContextContract) { | |
ctx.response.error('Invalid Token', error.code, error.status) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
|-------------------------------------------------------------------------- | |
| Application middleware | |
|-------------------------------------------------------------------------- | |
| | |
| This file is used to define middleware for HTTP requests. You can register | |
| middleware as a `closure` or an IoC container binding. The bindings are | |
| preferred, since they keep this file clean. | |
| | |
*/ | |
import Server from '@ioc:Adonis/Core/Server' | |
/* | |
|-------------------------------------------------------------------------- | |
| Global middleware | |
|-------------------------------------------------------------------------- | |
| | |
| An array of global middleware, that will be executed in the order they | |
| are defined for every HTTP requests. | |
| | |
*/ | |
Server.middleware.register([ | |
() => import('@ioc:Adonis/Core/BodyParser'), | |
]) | |
/* | |
|-------------------------------------------------------------------------- | |
| Named middleware | |
|-------------------------------------------------------------------------- | |
| | |
| Named middleware are defined as key-value pair. The value is the namespace | |
| or middleware function and key is the alias. Later you can use these | |
| alias on individual routes. For example: | |
| | |
| { auth: () => import('App/Middleware/Auth') } | |
| | |
| and then use it as follows | |
| | |
| Route.get('dashboard', 'UserController.dashboard').middleware('auth') | |
| | |
*/ | |
Server.middleware.registerNamed({ | |
auth: () => import('App/Middleware/Auth'), | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment