Code Monkey home page Code Monkey logo

knock-knock-knock's Introduction



KKK

TOC

KKK abbr. knock-knock-knock

Description

An authorization framework!

Features

  • extremely lightweight
  • zero dependencies
  • compatible with express
  • RESTful design
  • easy use with openid and oauth 2.0
  • easy to customize

Install

  • yarn:
yarn add knock-knock

# install needed schemas
# yarn add knock-google-openid
# yarn add knock-jwt-schema
  • npm:
npm install knock-knock

# install needed schemas
# npm install knock-google-openid
# npm install knock-jwt-schema

Example

basic example

let express = require('express');
let app = express();

app.use(express.json());

const KKK = require('../');
const kkk = new KKK({});

const schemaForKKK=require('./test-schema');

kkk.enable('test',schemaForKKK ,true);

app.post('/login', kkk.knockLogin('test'), (req, res, next) => {
    res.send('okay');
});

module.exports = app;

a full example for google open-id login and jwt auth

let express = require('express');
let cookieParser = require('cookie-parser');
let app = express();

app.use(express.json());
app.use(cookieParser('yijiang'));
app.use(express.urlencoded({extended: false}));

const KKK = require('knock-knock-knock');
let kkk = new KKK();

let googleSchemaClass = require('knock-google-openid');
let jwtSchemaClass = require('knock-jwt-schema');

// openid discovery method
googleSchemaClass.discovery().then((googleSchema) => {
    kkk.enable('google', googleSchema);
    kkk.enable('jwt', new jwtSchemaClass({secret: 'top-secret'}));
}).catch((err) => {
    console.error(err);
});

// oauth request step
app.get('/login', kkk.oauthLogin('google', {
    authSession: true,
    authSchemaID: 'jwt'
}));

// oauth callback step
app.get('/oauthcallback', kkk.knockLogin('google'), (req, res) => {
    if (req.user) {
        res.send(req.user);
    }
});

// jwt authorization
app.get('/dashboard', kkk.knockAuth('jwt'), (req, res) => {
    if (req.user) {
        res.send(req.user);
    }
});


app.use(function (err, req, res, next) {
    //deal with KKK's error
    if (err instanceof KKK.UnauthorizedError) {
        console.error(err);
        res.status(err.status).send(err);
    } else {
        res.status(500).send('interal error');
    }
})

module.exports = app;

Custom Schemas

in KKK there is two types of schema: login and auth.

  • login schema used as login or authentication. use this to get a login method
app.post('/login', kkk.knockLogin('test'), (req, res, next) => {
    res.send('okay');
});
  • auth schema used as create/revoke session and authorization. use this to get a auth method
app.get('/dashboard', kkk.knockAuth(), (req, res, next) => {
    if (req.user) {
        res.send(req.user);
    }
});

here is an example: this example show how to implements a schema

module.exports = function () {
    //login schema must implement this
    this.knockLogin = this.login = async function (req, res) {
        //you should check the login request from req
        //and must set one of them:

        // req.user =...
        // or
        // req.unauthorizedError = new KnockKnock.unauthorizedError();
    };

    //auth schema must implement this
    this.knockAuth = this.auth = async function (req, res) {
        //you should verify a session here...
        //and must set one of them:

        // req.user =...
        // or
        // req.unauthorizedError = new KnockKnock.unauthorizedError();
    }

    //optional for auth schema
    this.createSession = async function (req, res) {
    }
    this.revoke = function (req, res) {
    }

    //optional for login schema
    this.oauthCallback = function (req, res) {
    }
    this.oauthLogin = function (req, res) {
    }

};

every function here has same signature: async func(req,res),so you can:

  • return a Promise
  • use req,res same as express
  • set req.user as user object if login/auth approved
  • set req.UnauthorizedError to a KKK.UnauthorizedError if login/auth fatal
  • get req.user to verify user info(e.g. query database) because KKK's login schema(e.g knock-password-schema) only check the request but not verify it.
  • get req.user._schemaID specified which schema created this user object

More Specific

this shows how KKK internal flow

kkk.knockLogin
    =>(internal)loginSchema.knockLogin
    =>(internal)user `verify` function
    =>(internal)authSchema.createSession
kkk.knockAuth
    =>(internal)authSchema.knockAuth
    =>(internal)user `verify` function

so you have to:

  • set verify option if you want to verify request when you call kkk.knockLogin/kkk.knockAuth
  • specify createSession option if you want to create session otherwise it going to be one time authentication/authorization

Interface

  • call kkk.knockLogin(schema) and kkk.knockAuth(schema) is the most common way.
  • if you omit the schema option, kkk will try to refer it from client request:
_getParamFromReq(req, param) {
return req.params[param] || req.query[param] || req.cookies[param] || req.body[param];
}
  • kkk has shortcuts to directly get schema's methods, so after that you are able to pass it to express: you are able to use these shortcuts to get schema's method
//for login-schemas
kkk.login('test-schema');
kkk.oauthCallback('test-schema');
kkk.oauthLogin('test-schema');

//for auth-schemas
kkk.auth('test-schema');
kkk.revoke('test-schema')

options

verify

set verify will be called after kkk.knockLogin is called

kkk.knockLogin(
    'schema',
    {
        verify: async (req, res) => {
            return await database.query(req.user);
        }
    }
)

//or set globally...
kkk.option.globalLoginVerify = async (req, res) => {
    //...
}

kkk option

  • globalLoginVerify:the global login verify function
  • globalAuthVerify:the global auth verify function
  • throwUnauthorizedError:should throw error when unauthorized-error occurs otherwise kkk just only set req.unauthorizedError

API

Classes

UnauthorizedErrorError

A Unauthorized Error

KnockKnockKnock

knock-knock-knock main class

Functions

userVerifyFunction(req, res)

Interfaces

schemaInterface

schemaInterface

Kind: global interface
Ee: ./doc/examples/all-schema.js

schemaInterface.interface

a schema must implement one of the interface's methods

Kind: static interface of schemaInterface

interface.knockLogin(req, res)

must implement for login-schema.

Kind: static method of interface
Ee: ./doc/examples/login-schema.js

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

interface.knockAuth(req, res)

must implement for auth schema.

Kind: static method of interface
Ee: ./doc/examples/auth-schema.js

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

schemaInterface.loginOptional

if the schema implemented this interface , it is able to use [schemaFunctions] to call this function in schema

Kind: static interface of schemaInterface

loginOptional.login(req, res)

Kind: static method of loginOptional

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

loginOptional.oauthLogin(req, res)

Kind: static method of loginOptional

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

loginOptional.oauthCallback(req, res)

Kind: static method of loginOptional

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

schemaInterface.authOptional

if the schema implemented this interface , it is able to use [schemaFunctions] to call this function in schema

Kind: static interface of schemaInterface

authOptional.createSession(req, res)

Kind: static method of authOptional

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

authOptional.auth(req, res)

Kind: static method of authOptional

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

authOptional.revoke(req, res)

Kind: static method of authOptional

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

UnauthorizedError ⇐ Error

A Unauthorized Error

Kind: global class
Extends: Error

unauthorizedError.schema

Kind: instance property of UnauthorizedError

unauthorizedError.rawError

Kind: instance property of UnauthorizedError

KnockKnockKnock

knock-knock-knock main class

Kind: global class
Ee: ./doc/examples/newKKK.js

new KnockKnockKnock([option])

Param Type
[option] Option

knockKnockKnock.valid ⇒ boolean

check able to work available to work. it won't return true until least one login-schema are enabled

Kind: instance property of KnockKnockKnock

knockKnockKnock.enable(id, schema, setDefault)

enable a schema knock-knock-knock won't work until at least one login schema is enabled

Kind: instance method of KnockKnockKnock

Param Type Default Description
id string schama id
schema schemaInterface schema
setDefault boolean false default use the schema if user won't specify a schema id

Example

kkk.enable('test',schemaForKKK ,true);

knockKnockKnock.disable(id)

disable a schema

Kind: instance method of KnockKnockKnock

Param Type Description
id string schema id

Example

kkk.disable('test');

knockKnockKnock.lazy(router)

Kind: instance method of KnockKnockKnock
Todo

  • implement this
Param
router

knockKnockKnock.knockLogin([id], [option])

authenticate a request

Kind: instance method of KnockKnockKnock
Ee: ./doc/examples/knockLogin.js

Param Type Default Description
[id] string null schema id
[option] actionOptions {}

knockKnockKnock.knockAuth([id], [option])

authorize a request

Kind: instance method of KnockKnockKnock
Ee: ./doc/examples/knockAuth.js

Param Type Default Description
[id] string null schema id
[option] actionOptions {}

knockKnockKnock.[schemaFunctions](id, options)

return the functions from schema who implemented the interface loginOptional and authOptional

e.g if a schema which implements oauthLogin it could call knockKnockKnock.oauthLogin(id,option)

Kind: instance method of KnockKnockKnock
Ee: ./doc/examples/KKKLazy.js

Param Type Description
id string schema id enable
options actionOptions

KnockKnockKnock~Option

Kind: inner typedef of KnockKnockKnock
Properties

Name Type Default Description
[globalLoginVerify] userVerifyFunction the global login verify function
[globalAuthVerify] userVerifyFunction the global auth verify function
[throwUnauthorizedError] boolean true should throw error when unauthorized-error occurs otherwise kkk just only set req.unauthorizedError

KnockKnockKnock~actionOptions

Kind: inner typedef of KnockKnockKnock
Properties

Name Type Default Description
verify userVerifyFunction verify function for current user object in req.user
[authSession] boolean true should invoke authSchema to create session after login
authSchemaID string | undefined auth-schema id to create session after login. undefined to use default schema

userVerifyFunction(req, res)

Kind: global function
Ee: ./doc/examples/kkkverify.js

Param Type Description
req Object req.user should be set if user authorized or req.unauthorizedError should be set if error
res Object same like express

License

MIT

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.