【Express.js】全面鉴权

全面鉴权

这一节我们来介绍一下 Passport.js,这是一个强大的 NodeJS 的认证中间件

Passport.js 提供了多种认证方式,账号密码、OpenID、ApiKey、JWT、OAuth、三方登录等等。

使用 Passport.js 认证要配置三个部分:

  1. 认证策略
  2. 中间件
  3. 会话

接下来我们以 账号密码 认证为例,来演示一下 Passport.js 的使用

准备工作

新建一个基础的 evp-express 项目

安装依赖

  1. 安装 passport.js
shell 复制代码
npm install passport
  1. 安装 local 策略
shell 复制代码
npm install passport-local

创建页面

在 public 目录下面创建 index.html, fail.html, home.html 3个页面:

index.html:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <form action="/login" method="post">
    <input name="username" placeholder="username..." />
    <input name="password" placeholder="password..." />
    <button type="submit">Login</button>
  </form>
</body>
</html>

fail.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Fail</title>
</head>
<body>
  <h1>Fail</h1>
  <a title="gologin" href="/views">Go login</a>
</body>
</html>

home.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Home</title>
</head>
<body>
  <h1>Hello, Home!</h1>
</body>
</html>

设置静态目录

app.js:

js 复制代码
const config = require('./config.js').get();
//...
app.use('/views', express.static(config.public, { extensions: ['html'] }));

这个 extensions 选项用于允许访问静态页面不带 html 后缀。

开启Session

app.js:

javascript 复制代码
//...
app.use(session({
  secret: 'secret',
  resave: false,
  saveUninitialized: true
}));

初始化passport

app.js:

javascript 复制代码
const passport = require('passport');

//...
app.use(passport.initialize());
app.use(passport.session());

设置认证

步骤:

  1. 使用策略,规定认证过程,done是回调函数,可以接收三个参数:
  2. 异常
  3. 在会话中保存的用户信息,填 false 代表认证失败
  4. 其余数据,比如传递信息
  5. 序列化用户信息
  6. 反序列化用户信息
    app.js:
javascript 复制代码
const LocalStrategy = require('passport-local').Strategy;

//...
passport.use(new LocalStrategy(
  function verify(username, password, done) {
    if (username == 'root' && password == 'root') {
      return done(null, { username, password});
    }
    return done(null, false, {message: "None"});
  }
))

passport.serializeUser((user, cb) =>{
  process.nextTick(()=>{
    cb(null, {username: user.username, password: user.password})
  })
})

passport.deserializeUser((user, cb) => {
  process.nextTick(()=>{
    return cb(null, user);
  });
});

编写登录接口

router/index.js:

javascript 复制代码
const { Json, Form, Multi, FromPlus } = require('../midwares/bodyParser');

//...
router.post('/login', FromPlus, passport.authenticate('local', {
  failureRedirect: '/views/fail',
  failureFlash: false
}), (req, res, next) => {
  res.redirect('/views/home');
});

前端页面在表单中填写登录信息,先按照表单格式解析一下,然后再加入 passport 的认证中间件,指定策略为 local, 并指定认证失败跳转到 fail.html,成功则重定向到 homte.html,这个可以和失败重定向一样,作为 successRedirect 选项写到上面。

保护接口

编写一个判断时候登录的中间件函数:

js 复制代码
function isLogined(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect('/views/');
}

/ 路由进行登录保护:

js 复制代码
router.get('/', isLogined, (req, res, next) => {
  logger.info('Hello World!');
  res.json(Resp.ok('Hello World!', 1, null));
});

测试

此时运行项目,在浏览器中访问http://127.0.0.1:8080,会被重定向到登录界面,登录成功后在地址栏可以正常访问到这个被保护的路由,登录失败则会被重定向到 fail 页面。

Passport.js 的更多用法请自行探索,详见官方文档:https://www.passportjs.org/docs/

下一节-软件测试

相关推荐
放下华子我只抽RuiKe52 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架
XinZong2 小时前
OpenClaw 实现双重心跳(Heartbeat)+ clawreach虾聊项目实现
javascript
IT_陈寒3 小时前
Redis缓存击穿把我整不会了,原来还有这手操作
前端·人工智能·后端
kyriewen4 小时前
面试官让我查各部门工资最高的员工,我用AI三秒写出窗口函数,他愣了
后端·mysql·面试
文心快码BaiduComate4 小时前
干货|Comate Harness Engineering工程实践指南
前端·后端·程序员
还有多久拿退休金4 小时前
一张栈的图,治好你面试答不出 script 阻塞的病
前端·javascript
光辉GuangHui4 小时前
Agent Skill 也需要测试:如何搭建 Skill 评估框架
前端·后端·llm
我是谁的程序员4 小时前
Mac 上生成 AppStoreInfo.plist 文件,App Store 上架
后端·ios
zithern_juejin4 小时前
原型与原型链
javascript
irving同学462384 小时前
Node 后端实战:JWT 认证与生产级错误处理
前端·后端