-
Notifications
You must be signed in to change notification settings - Fork 0
Authentication guards
An authentication guard is used to create authentication for your platform, and is based on the Symfony's security package. The idea is that you create guards that can be used to authenticate a user, but allow you to define many guards, so one could be to authenticate a user via API tokens, think other applications, or using login and password, from a front-end. Each guard manages it's own state.
There is a default guard that is included which is the AbstractGuard, see the documentation on how to use this, this actually logs the different states of what is called. We suggest you either extend the AbstractGuard
or implement the IGuard
interface to make sure you write the correct code.
NOTE: All methods are fully commented in the code if you are more interested to read code.
Remember that if no default guard is available, and all guards fail to respond, then a user could access the platform without authentication, so we suggest for production you always have a default guard, even if that guard just triggers the
onAuthenticationFailed
method to stop users from getting access.
import { Guard, AbstractGuard, IGuard } from 'rewyre';
// The guard takes the guard name, and then whether it is the default guard.
@Guard('default', true)
export class FormLoginGuard extends AbstractGuard implements IGuard {}
The below defines the methods in each guard, the required parameters and then response.
The supports method will be called on every request to the API, this will take the request and check for available information from the raw request object from Express, and if it can find the right information, then it will return true or false, depending on whether that guard supports that request. Example could be if you are using login and password authentication, then checking if that request is a POST request to a /login
path with the username and password data given.
This method is used to actually get the data from the request, this is where you actually aggregate the data to be given to the next step, we suggest this is where you do more, as remember the supports
function is called every request, where as this request is only called if the supports
function suceeeds.
This method is called after the getCredentials
function and is passed the result of that method, this function should be where you attempt to call your user class or the place in which you want to verify an account to the given credentials, but do not do any validation in here, that is done in the next step, this should only return the object. You can return false, to trigger the onAuthenticationFailed
method.
This method is called after getUser
and passed all the data, here you should do all of the verification of a user, to checking passwords, or API tokens, and validating the user. Depending on the outcome you should respond with true or false, of course responding false will call onAuthenticationFailed
and returning true will call the onAuthenticationSuccess
method.
This method is called when either the getUser
or checkCredentials
methods fail, and therefore you will have access to the request, the credentials and a user if you got that far in the authentication flow. Here you can log any errors, by default we will respond with a 401 Unauthorised
automatically, but this allows you to collect the data and log it, by default the Logger
module is included in the AbstractGuard
class.
This method is called when everything returns correctly and no errors are found, by default the application will execute this function, but keep on processing, and therefore this function is simply to add logging, add audit logs or any clean-up you need to do. The user object is stored against the context
object that is given to every controller, so you can access the output of that (if logged in and passed a authentication guard) in the authentication
property of the context
object, see demo below.
import { Controller, AbstractController, Route, IContext, IReturn } from 'rewyre';
@Controller('/test', 'test')
export class MyController extends AbstractController {
@Route('GET', '/foo')
public example_method(context: IContext): Promise<IReturn> {
console.log(context.authentication);
}
}