npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

express-security

v0.7.8

Published

lightweight authentication/authorization express middleware

Downloads

21

Readme

express-security

一套Express中间件,轻量,用于根据当前用户是否登陆、及其拥有的角色来拦截请求。

使用说明

目前使用AuthenticationInterceptorAuthorizationInterceptorAuthInterceptor 类作为对外统一接口。三个类的职责为:

  • AuthenticationInterceptor: 负责认证检查
  • AuthorizationInterceptor:负责授权检查
  • AuthInterceptor:负责认证和授权检查,只是以上两个类的包装
  1. 根据需要,实例化一个AuthenticationInterceptorAuthorizationInterceptor、或者AuthInterceptor拦截器
  2. 使用拦截器拦截请求

默认情况

默认的实现是基于session机制:

  • 默认情况下,需要确保 req.session 的可用性。
  • 默认情况下,对客户端的用户名判断是通过req.session.username实现的。如果要定制,需要自行提供登陆检查器。
  • 默认情况下,对客户端的角色判断是通过req.session.roles实现的。如果要定制,需要自行提供角色访问器。

所以,这时候往往需要安装第三方模块保证session可用,比如使用express-session中间件:

> npm install express-session --save

使用之前需要实例化出一个对象:


// initialize a authentication-interceptor
const authenInterceptor=new AuthenticationInterceptor();

// initialize a authorization-interceptor
const authorInterceptor=new AuthorizationInterceptor();

// or just initialize a auth-interceptor
const interceptor=new AuthInterceptor();

自定义配置

尽管默认的配置是基于session的,但是,AuthInterceptorAuthenticationInterceptor、和AuthorizationInterceptor的检查机制并不和 session 耦合在一起。 通过提供自定义登陆检查器角色访问器,完全可以丢掉 session

  1. 登陆检查器:函数对象,接收请求req参数,同步返回(或者以等价的异步的方式“返回”)当前用户是否登陆的boolean值,
  2. 角色访问器: 函数对象,接收请求req参数,同步返回(或者以等价的异步的方式“返回”)当前用户所拥有的角色列表。放心,拦截器只会对“返回”的角色列表读操作。

可以通过AuthenticationInterceptorAuthorizationInterceptor实现自定义:


// 认证拦截器
const authenticationInterceptor=new AuthenticationInterceptor(
    (req)=>{return !!req.session.username;},  // 覆盖默认的登陆检查器
);

// 授权拦截器
const authorizationInterceptor=new AuthorizationInterceptor(
    (req)=>{return req.session.roles;}        // 覆盖默认的角色访问器
);

// 如果你认证/授权都需要的话:
const authInterceptor=new AuthInterceptor(
    (req)=>{return !!req.session.username;},  // 覆盖默认的登陆检查器
    (req)=>{return req.session.roles;}        // 覆盖默认的角色访问器
);

当前,还可以提供msg对象作为附加的默认返回消息(详见代码实现),但是大多情况下,不需要定制此参数。

异步式

除了上面演示的同步式的登陆检查器和角色访问器,还可以使用异步式进行定制:


// 支持各类异步方式:比如可以以Promise的方式进行检查
const authenticationInterceptor=new AuthenticationInterceptor(
    // 覆盖默认的登陆检查器
    (req)=>{
        return new Promise(function(resolve,reject){
            resolve(!!req.session.username);
        });
    }
);

// 支持各类异步方式:还可以以callback的方式进行检查
const authorizationInterceptor=new AuthorizationInterceptor(
    // 覆盖默认的角色访问器
    (req,callback)=>{
        setTimeout(function() {
            callback(null,req.session.rolelist);
        }, 100);
    }
);

const interceptor=new AuthInterceptor(
    (req)=>{return !!req.session.username;},
    (req)=>{
        return new Promise(function(resolve,reject){
            resolve(req.session.rolelist);
        });
    }
);

除此之外,requireTrue()方法也支持使用异步式进行拦截:

const interceptor=new AuthorizationInterceptor();

interceptor.requireTrue(function(req){
    return Promise.resolve(req.sth);
});

如何拦截请求

AuthenticationInterceptorAuthorizationInterceptor实例对请求的拦截是利用express中间件原理实现的。 拦截器实例对象有一系列requireXxx()方法,比如

  1. requireLogin()
  2. requireRole()
  3. requireAnyRole()
  4. requireAllRoles()
  5. requireTrue()

AuthInterceptorrequireXxx()只是简单调用AuthenticationInterceptorAuthorizationInterceptor的相应requireXxx()方法。 每个这种方法都是一个高阶函数,调用后会返回一个中间件函数,用于拦截请求:

// 要求拥有 "ROLE_ROOT" 角色,否则提示失败消息然后重定向到根目录"/"
router.use("/admin",interceptor.requireRole("ROLE_ROOT","/"));

安装与测试

通过npm安装:

> npm install express-security --save

测试:

> npm run test

使用示例

可以根据需要,分别实例化一个AuthenticationInterceptorAuthorizationInterceptor

const express=require('express');
const {AuthInterceptor,AuthenticationInterceptor,AuthorizationInterceptor}=require('express-security');

const router=express.Router();

const authenInterceptor=new AuthencationInterceptor(
    (req)=>{return !!req.session.username;},
);

const interceptor=new AuthorizationInterceptor(
    (req)=>{return req.session.roles;}
);

// 要求登陆
router.use('/dashboard',authenInterceptor.requireLogin());

// 要求登陆,自定义重定向页面
router.use('/user/detail',authenInterceptor.requireLogin("/account"));

// 要求拥有 "ROLE_ADMIN" 角色
router.use("/admin",interceptor.requireRole("ROLE_ADMIN","/"));

// 要求拥有 "ROLE_ROOT"、"ROLE_ADMIN" 中任意一个角色
router.use("/sudo",interceptor.requireAnyRole(["ROLE_ROOT","ROLE_ADMIN"]));

// 要求拥有 "ROLE_0"、"ROLE_1"、"ROLE_2" 中全部角色
router.use("/holy",interceptor.requireAllRoles(["ROLE_0","ROLE_1","ROLE_2"]));

// 要求返回正确值的可调用对象
router.use("/shit",interceptor.requireTrue((req)=>{return !! req.query.sth;},"/"));

如果同时需要根据用户登录状态和角色信息对请求进行拦截,也可以直接实例化一个AuthInterceptor作为统一的外部接口。

const AuthInterceptor=new AuthInterceptor(
    (req)=>{return !!req.session.username;},
    (req)=>{return req.session.roles;}
);

案例

参见我的这篇笔记:ASP.NET 与 Node.js 的协作实践