Authentication through cookies - kplian/pxp-nd GitHub Wiki
1.- We are going to make an authentication request that will create a cookie that will contain encrypted variables where the session data will be handled. We need to install two libraries that are from pxp:
-
Auth
It contains what is necessary to initialize the creation, management and control of routes, it has a custom middleware.
-
Common
It contains a set of entities and controllers that will serve us in different projects in this case to perform the authentication.
Inside our config file we are going to add the auth, session, this variable receives as a parameter a Session entity that we import from @pxp-nd/common
import { IConfigPxpApp } from '@pxp-nd/core';
import { customMiddleware } from './middlewares';
import { Session } from '@pxp-nd/common';
const config: IConfigPxpApp = {
defaultDbSettings: 'Orm', // Orm, Procedure, Query
apiPrefix: '/api',
logDuration: true,
showRoutes: true,
middlewares: [customMiddleware],
auth:true,
session: Session,
};
export default config;
And in the ormconfig file we are also going to import the session from @pxp-nd/common, it will be in an entity parameter which is an array that receives a set of entities. This entities parameter is important to configure when we are going to use some modules, subsystems that are already packaged and are not included in our project that could be found in a library, where we can inject all the entities that have common to be able to handle translations, roles, users, etc.
const { createConnections } = require('@pxp-nd/core');
const {Session} = require('@pxp-nd/common');
/** You can use these parameters
* synchronize: boolean, - Indicates if database schema should be auto created on every application launch.
* Be careful with this option and don't use this in production -
* otherwise you can lose production data.
* logging: boolean, - If set to true then query and error logging will be enabled.
**/
const connection = {
name: 'default',
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'admin',
database: 'dbapp_pxp',
synchronize: true,
entities: [Session],
};
module.exports = createConnections(connection);
2.- Now we are going to make the necessary configuration so that the authentication works correctly. We are also going to need the user entity and we are going to inject the necessary controllers to handle this user, entities: [User], controllers: [userController]. These two settings have to go together so that your routes can be created correctly.
We are also going to configure the authentication middleware, importing it from @ pxp-nd / auth.
import { IConfigPxpApp } from '@pxp-nd/core';
import { customMiddleware } from './middlewares';
import { Session, User, UserController } from '@pxp-nd/common';
import { isAuthenticated } from '@pxp-nd/auth';
const config: IConfigPxpApp = {
defaultDbSettings: 'Orm', // Orm, Procedure, Query
apiPrefix: '/api',
logDuration: true,
showRoutes: true,
middlewares: [ isAuthenticated ],
auth: true,
session: Session,
entities: [ User ],
controllers: [ UserController ],
};
export default config;
We must also do the configuration in the ormconfig file where we are going to configure, Roles, Person, Subsystem, Transaction, Ui, UiTransaction.
const { createConnections } = require('@pxp-nd/core');
const { Session, User, Role, Person, Subsystem, Transaction, Ui, UiTransaction } = require('@pxp-nd/common');
/** You can use these parameters
* synchronize: boolean, - Indicates if database schema should be auto created on every application launch.
* Be careful with this option and don't use this in production -
* otherwise you can lose production data.
* logging: boolean, - If set to true then query and error logging will be enabled.
**/
const connection = {
name: 'default',
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'admin',
database: 'dbapp_pxp',
synchronize: true,
logging: false,
entities: [ Session, User, Role, Person, Subsystem, Transaction, Ui, UiTransaction ]
};
module.exports = createConnections(connection);
The last configuration I need is to initialize the authentication in my application, inside the server.ts file, which will receive a configAuth configuration that is a function that is in the Auth package.
* @summary Stars server.
* @author Jaime Rivera
*
* Created at : 2020-06-13 18:09:48
* Last modified : 2020-09-17 18:38:16
*/
import 'dotenv/config';
import App from './App';
import { configAuth } from '@pxp-nd/auth';
const app = new App();
(async function() {
try {
await app.run();
await app.initializeAuthentication( configAuth );
app.listen();
} catch (e) {
console.log(e);
}
}());
We start the server again with the command npm run dev
Carrying out all these steps, we have the authentication ready. Now we are going to perform a test with our service in Postman using the GET method as follows, http://localhost:3200/api/backend-nd/persons?id=222&name=kplian
And as we can see, it has just carried out the verification if that request is authenticated, when we automatically enable authentication all our routes need to have an authentication, for this reason it returns the following error.
{
"error": true,
"message": "Not Authorized"
}
In this case we will use the @Authentication () decorator in the Person controller where we pass it as true / false parameters, to verify if it needs to be authenticated or not, in this example it will be false.
@Get('/:personId?')
@ReadOnly(true)
@DbSettings('Orm')
@Authentication(false)
async find (params: any): Promise<any>{
console.log('PARAMAS', params);
const manager = getManager();
const where = params.personId ? {personId: params.personId}: {};
return await manager.find(PersonModel, {
where,
relations: ['tasks']
});
}
}
And we can see that we are correctly receiving the list, where it did not do the authentication check.
{
"error": true,
"message": "Not Authorized"
}
In this case we will use the @Authentication () decorator in the Person controller where we pass it as true / false parameters, to verify if it needs to be authenticated or not, in this example it will be false.
[
{
"personId": 4,
"name": "Luis",
"phone": "44444",
"tasks": [
{
"taskId": 12,
"description": "task 6",
"status": "unfinished",
"personId": 4
},
{
"taskId": 13,
"description": "task 7",
"status": "unfinished",
"personId": 4
}
]
},
{
"personId": 11,
"name": "Luis",
"phone": "44444",
"tasks": []
},
{
"personId": 5,
"name": "Kplian",
"phone": "12345",
"tasks": []
},
]
