Options
All
  • Public
  • Public/Protected
  • All
Menu

@thermopylae/core.jwt-session

@thermopylae/core.jwt-session

Version Node Version Documentation License: MIT

JWT user session for HTTP interface.

Install

npm install @thermopylae/core.jwt-session

Description

This package contains Http Middleware for jwt user session management. It uses @thermopylae/lib.jwt-user-session for session management and contains implementation for repositories required by the library.

Usage

import { LoggerManagerInstance, OutputFormat } from '@thermopylae/core.logger';
import { ConnectionType, initLogger as initRedisClientLogger, RedisClientInstance, RedisConnectionOptions } from '@thermopylae/core.redis';
import { initLogger as initUserSessionCommonsLogger, UserSessionRedisStorage } from '@thermopylae/core.user-session.commons';
import { FastifyRequestAdapter, FastifyResponseAdapter, AdaptedFastifyRequest, LOCATION_SYM } from '@thermopylae/core.adapter.fastify';
import { GeoIpLocator, GeoIpLiteRepository } from '@thermopylae/lib.geoip';
import { AVRO_SERIALIZER } from '@thermopylae/core.user-session.commons/dist/storage/serializers/jwt/avro';
import { FastifyReply } from 'fastify';
import { HttpStatusCode } from '@thermopylae/core.declarations';
import { initLogger as initCoreJwtSessionLogger, InvalidAccessTokensMemCache, JwtUserSessionMiddleware } from '@thermopylae/core.jwt-session';

(async function main() {
    /* Configure logging */
    LoggerManagerInstance.formatting.setDefaultFormattingOrder(OutputFormat.PRINTF);
    LoggerManagerInstance.console.createTransport({ level: 'info' });

    /* Init loggers */
    initRedisClientLogger();
    initCoreJwtSessionLogger();
    initUserSessionCommonsLogger();

    /* Connect to Redis Server */
    const redisClientOptions: RedisConnectionOptions = {
        host: '127.0.0.1',
        port: 6379,
        password: '09}KNng90/mng89;',
        connect_timeout: 10_000,
        max_attempts: 10,
        retry_max_delay: 5_000,
        attachDebugListeners: new Set(['end', 'reconnecting'])
    };

    await RedisClientInstance.connect({
        [ConnectionType.REGULAR]: {
            ...redisClientOptions,
            detect_buffers: true // very important, REQUIRED
        },
        [ConnectionType.SUBSCRIBER]: redisClientOptions
    });

    /* Enable Key Space Notification Events (REQUIRED) */
    await RedisClientInstance.client.config('SET', 'notify-keyspace-events', 'Kgxe');

    /* Configure Geoip (OPTIONAL) */
    const geoip = new GeoIpLocator([new GeoIpLiteRepository(1)]);

    /* Configure Middleware */
    const middleware = new JwtUserSessionMiddleware({
        jwt: {
            secret: 'secret',
            signOptions: {
                algorithm: 'HS384',
                issuer: 'auth-server.com',
                audience: ['auth-server.com', 'rest-server.com'],
                expiresIn: 900 // 15 min
            },
            verifyOptions: {
                algorithms: ['HS384'],
                issuer: 'auth-server.com',
                audience: 'rest-server.com'
            },
            invalidationOptions: {
                refreshTokenTtl: 86_400, // 24h
                refreshTokenLength: 24,
                invalidAccessTokensCache: new InvalidAccessTokensMemCache(),
                refreshTokensStorage: new UserSessionRedisStorage({
                    keyPrefix: {
                        sessions: 'reftoks',
                        sessionId: 'reftok'
                    },
                    concurrentSessions: 3,
                    serializer: AVRO_SERIALIZER
                })
            }
        },
        session: {
            cookies: {
                name: {
                    signature: 'sig',
                    payload: 'pld',
                    refresh: 'rfsh'
                },
                path: {
                    'access-payload': '/',
                    'access-signature': '/api',
                    refresh: '/session'
                },
                sameSite: 'strict',
                persistentAccessToken: true
            },
            headers: {
                access: 'x-access-token',
                refresh: 'x-refresh-token'
            },
            csrfHeader: {
                name: 'x-requested-with',
                value: 'XmlHttpRequest'
            },
            deliveryOfJwtPayloadViaCookie: true,
            'cache-control': true
        }
    });

    /* Define Route Handler */
    async function createSession(req: AdaptedFastifyRequest, res: FastifyReply): Promise<void> {
        const request = new FastifyRequestAdapter(req);
        const response = new FastifyResponseAdapter(res);

        req[LOCATION_SYM] = await geoip.locate(request.ip);

        try {
            await middleware.create(request, response, { role: 'user' }, { subject: 'uid1' });
            response.status(HttpStatusCode.Created).send();
        } catch (e) {
            response.status(HttpStatusCode.BadRequest).send({ message: e.message });
        }
    }
})();

API Reference

API documentation is available here.

It can also be generated by issuing the following commands:

git clone git@github.com:marinrusu1997/thermopylae.git
cd thermopylae
yarn install
yarn workspace @thermopylae/core.jwt-session run doc

Author

👤 Rusu Marin

📝 License

Copyright © 2021 Rusu Marin.
This project is MIT licensed.