1.2.0 • Published 7 years ago

@patrickkeller/fishy-auth v1.2.0

Weekly downloads
1
License
ISC
Repository
-
Last release
7 years ago

Installation

npm install @patrickkeller/fishy-auth

Versionen

1.2.0

  • getResolvers gefixt.

1.1.1

  • SKIP_AUTH gefixt

1.1.0

  • Neue blacklistToken Funktion.
  • Resolver und Scope Struktur vereinfacht.

1.0.2

  • Update auf ES2017

1.0.2

  • Initiale Version mit Koa und Koa-Router Middlewares.

Config

JWT_KEY_PATH Default: 'src/config/keys/jwt.hs256'

SKIP_AUTH Default: false

Koa-Middleware

Token-Validierung für Koa2. Die Middleware setzt die beiden Werte ctx.state.resolvers und ctx.state.scope (Nur wenn scopesFunc vorhanden).

import { authToken } from '@patrickkeller/fishy-auth';
// ...
app.use(authToken(resolverFunc, scopesFunc));
// ...

Die Resolver-Funktion ist für das auflösen der Benutzerechte zuständig, diese könnte wie folgt aussehen:

import { Cache } from '@patrickkeller/fishy-redis';
import { Group } from "resources/group/group.model";

/**
 * Fügt alle Resolver zu einem Array zusammen
 * @param groups
 * @returns {Array}
 */
function mergeResolvers(groups: Array<any>) {
  let out = [];
  let i = groups.length;

  while (i--) {
    const resolver = groups[i].resolvers;
    if (Array.isArray(resolver)) { out.push(resolver); }
  }

  return lo.union(...out);
}

/**
 * Gibt Resolver pro User zurück
 * @param user
 * @returns {Promise<Array<string>>}
 */
export async function getResolvers(user) {
  let cacheExists = await Cache.existsAsync(`cache:${user._id}:resolvers`);

  if (process.env.CACHE_RIGHTS !== 'true') { cacheExists = false; } // Cache ist per default deaktiviert

  if (!cacheExists) {
    let groups: any = await Group.find({ _id: { $in: user.groups } }).lean().exec();

    const resolvers = mergeResolvers(groups);

    await Cache.setAsync(`cache:${user._id}:resolvers`, JSON.stringify(resolvers));

    return resolvers;
  } else {
    const resolvers = await Cache.getAsync(`cache:${user._id}:resolvers`);

    return JSON.parse(resolvers);
  }
}

Die Scopes-Funktion ist für das auflösen von evt. Query-Einschränkungen (Scopes) zuständig, diese könnte wie folgt aussehen:

import { Cache } from '@patrickkeller/fishy-redis';
import { Group } from "resources/group/group.model";

/**
 * Fügt alle Scopes zu einem Object zusammen
 * @param groups
 * @returns {{}}
 */
function mergeScopes(groups) {
  let out = {};
  let i = groups.length;

  while (i--) {
    const scopes = groups[i].scopes;
    if (typeof scopes !== 'object') { continue; }
    let keys = Object.keys(scopes);
    let k = keys.length;

    while (k--) {
      let key = keys[k];
      if (!out.hasOwnProperty(key)) { out[key] = []; }
      out[key] = lo.union(out[key], scopes[key]);
    }
  }

  return out;
}

/**
 * Gibt Scopes pro User zurück
 * @param user
 * @returns {Promise<Array<string>>}
 */
export async function getScopes(user) {
  let cacheExists = await Cache.existsAsync(`cache:${user._id}:scopes`);

  if (process.env.CACHE_RIGHTS !== 'true') { cacheExists = false; } // Cache ist per default deaktiviert

  if (!cacheExists) {
    let groups: any = await Group.find({ _id: { $in: user.groups } }).lean().exec();

    const scopes = mergeScopes(groups);

    await Cache.setAsync(`cache:${user._id}:scopes`, JSON.stringify(scopes));

    return scopes;
  } else {
    const scopes = await Cache.getAsync(`cache:${user._id}:scopes`);

    return JSON.parse(scopes);
  }
}

Router-Middleware

Prüft ob ein Benutzer angemeldet ist und ob dieser Rechte hat auf die entsprechende Route. Die Middleware erwartet ein ctx.state.user und ein ctx.state.resolvers Objekt um dies zu prüfen.

import { authRoute } from '@patrickkeller/fishy-auth';
// ...
router.get('getUser', '/:id', authRoute, ctrl.show);
// ...