关于中间件

https://eggjs.org/zh-cn/basics/middleware.html

官方文档说的很清楚了,不再叙述。

我们要达到怎么样一个效果?

  1. 用户没有登录不能访问一些特定的页面,比如修改密码、修改资料啊这些敏感操作。如果用户没有登录访问这些页面会自动跳转到登录页面让用户登录。
  2. 如果用户登录过了就可以访问这些页面(验证通过。)
  3. 没有登录可以访问登录页面来进行登陆,或者注册等不需要权限的页面。

如果不使用中间件你会怎么写

在controller/user 修改密码,

async changePassword(){
if (this.ctx.session.userId) { // 如果有这个session
// 执行修改密码
} else {
// 不写就没有响应,会404
ctx.redirect('/login');
}
}

然后修改资料

async changeUserInfo(){
if (this.ctx.session.userId) { // 如果有这个session
// 执行修改资料
} else {
// 不写就没有响应,会404
ctx.redirect('/login');
}
}

然后登录就不用判断

async login(){
let {userName, password} = this.ctx.request,body;
// 校验密码
let userFind = this.service.findOne({userName, password});
// 获取user信息
if (userFind) {
this.ctx.session.userId = userFind._id;
// 返回成功
this.ctx.body = '登录成功';
} else {
this.ctx.body = '登录失败,账号密码错误';
}
}

这样如果代码量小的话也能接受,但是如果将来接口越来越多,需要检验权限的地方也越来越多,修改就会很麻烦。

剥离出来,自成体系

在app/middleware下面新建authLogin.js文件用来判断是否登录

module.exports = (options, app) => {

  return async function testMiddleware(ctx, next) {

    let whiteUrls = options.whiteUrls || [];

    // 如果ctx.url在白名单中
let isWhiteUrl = whiteUrls.some((whiteUrl)=> ctx.url.startsWith(whiteUrl)); if (! isWhiteUrl) {
console.log('authLogin');
if (! ctx.session.userId) {
ctx.redirect('/login'); // 让用户去登录
}
else {
console.log('auth ok');
await next();
}
} else {
// 白名单
console.log('white url');
await next();
}
};
};

在controller/user 修改密码,

async changePassword(){
//不需要判断,直接执行修改密码
}

然后修改资料

async changeUserInfo(){
//不需要判断,直接执行修改资料
}

然后登录还是一样

async login(){
let {userName, password} = this.ctx.request,body;
// 校验密码
let userFind = this.service.findOne({userName, password});
// 获取user信息
if (userFind) {
this.ctx.session.userId = userFind._id;
// 返回成功
this.ctx.body = '登录成功';
} else {
this.ctx.body = '登录失败,账号密码错误';
}
}

代码是不是精简清爽多了呢?

注意的几个点,

  1. 要加到config的middleware列表里面:
  config.middleware = [''authLogin'];
  1. await next()要放在最后,这样意味着校验规则会在路由匹配之前执行。
  2. whiteUrl是在config.default.js中的options配置,也可以不要这个,直接使用match或者ignore(相关规则参考官方文档关于中间件这一块)
  config.authLogin = {
whiteUrls: ['/test'], // 是使用url的前缀匹配的
// 不需要登录的页面,白名单URL
// 也可以使用
ignore: ['/login', '/register', '/doLogin', '/doRegister'] // 使用 match是限制只在这几个页面执行
// match和ignore不能同时使用
};
  1. 不配置 config.authLogin的话呢?只在特定路由中使用:
  router.get('/login', authLogin, controller.user.login);

谢谢观看,有什么问题欢迎留言评论,看到尽量会回复。。。

写一个eggjs权限验证中间件的更多相关文章

  1. nodejs异常处理过程/获取nodejs异常类型/写一个eggjs异常处理中间件

    前言 今天想写一下eggjs的自定义异常处理中间件,在写的时候遇到了问题,这个错误我捕获不到类型?? 处理过程,不喜欢看过程的朋友请直接看解决方法和总结 看一下是什么: 抛出的异常是检验失败异常Val ...

  2. 用GO写一个后台权限管理系统

    最近用GO写了一个后台权限管理系统,在WIN10和ubuntu下部署,在win系统下编译ububtu的部署文件要先做如下配置 set GOARCH=amd64 set GOOS=linux go bu ...

  3. web权限验证方法说明[转载]

    前言 本文将会从最基本的一种web权限验证说起,即HTTP Basic authentication,然后是基于cookies和tokens的权限验证,最后则是signatures和一次性密码. HT ...

  4. 【Filter 不登陆无法访问】web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面的功能

    在web项目中写一个过滤器实现用户不登陆,直接给链接,无法进入页面,而重定向到登陆界面的功能. 项目是用springMVC+spring+hibernate实现 (和这个没有多大关系) 第一步: 首先 ...

  5. 【Filter 页面重定向循环】写一个过滤器造成的页面重定向循环的问题

    今天做一个过滤器,碰上页面重定向循环的情况: 浏览器的访问路径是:http://192.168.16.104:8080/biologyInfo/login/login/login/login/logi ...

  6. Struts2 自定义拦截器实例—登陆权限验证

    实现一个登陆权限验证的功能 message.jsp: <body> message:${message } </body> login.jsp: <% request.g ...

  7. .net web api 权限验证

    做一个登录权限验证. 开始吧. using System; using System.Collections.Generic; using System.Drawing; using System.D ...

  8. AngularJS中巧用ngModel的$asyncValidators属性写一个验证唯一性的Direcitve

    有这样的一个需求:添加用户的时候,根据主键判断当前添加用户的email是否已经被使用. 为此,我们需要把主键和email来传递给远程的一个API,让API返回结果,告之当前email是否被使用过. 写 ...

  9. ########django-基于中间件写一个限制频繁登陆########

    django-基于中间件写一个限制频繁登陆 额额,标题已经很醒目了,通过中间件去实现,其他方法也可以实现 浏览器前端传来的请求,必须通过中间件,才能到后面路由,视图函数,所以我们在中间件那里做一层处理 ...

随机推荐

  1. 【转载】C#使用InsertRange方法往ArrayList集合指定位置插入另一个集合

    在C#的编程开发中,ArrayList集合是一个常用的非泛型类集合,ArrayList集合可存储多种数据类型的对象.在实际的开发过程中,我们可以使用InsertRange方法在ArrayList集合指 ...

  2. 使 WIN 10进入休眠、睡眠、关机的命令

    1.用命令控制定时关机,重启,休眠等 休眠:rundll32.exe powrProf.dll,SetSuspendState 休眠:shutdown -h 睡眠:rundll32.exe powrp ...

  3. Css3动画(一) 如何画3D旋转效果或者卫星围绕旋转效果

    如何画3D旋转效果或者卫星围绕旋转效果,当然这个也是工作中的一个任务,我在网上翻了一下,并没有找到类似的东西,所以写下来还是费了一番功夫,因此我把它拿出来记录一下,当然替换了一部分内容.好了,话不多说 ...

  4. 【转载】自定义View学习笔记之详解onMeasure

    网上对自定义View总结的文章都很多,但是自己还是写一篇,好记性不如多敲字! 其实自定义View就是三大流程,onMeasure.onLayout.onDraw.看名字就知道,onMeasure是用来 ...

  5. Linux service进程管理

    Linux进程基本介绍: 1)在Linux中,每个执行的程序(代码)都称为一个进程.每一个进程都分配一个ID号. 2)每一个进程,都对应一个父进程,而这个父进程可以复制多个子进程.例如www服务器. ...

  6. 如何将Android的AOSP仓库放置到自己的gitlab服务器上?

    平台 Ubuntu 18.04 GitLab Community Edition 11.11.0   参考 https://source.android.google.cn/   概述     git ...

  7. 软件测试生命周期(STLC)的8个阶段的详细信息

    一.演化 ♦1960年代的趋势: ♦1990年代的趋势: ♦2000年代的趋势: 测试的趋势和能力正在发生变化.现在要求测试人员更加注重技术和流程.现在的测试不仅仅局限于发现错误,而且范围更广,从项目 ...

  8. Vuex状态数据源state

    (1)单一状态树 Vuex 使用单一状态,用一个对象就包含了全部的应用层级状态.至此它便作为一个“唯一数据源 (SSOT)”而存在.这也意味着,每个应用将仅仅包含一个 store 实例. 单一状态树让 ...

  9. Nuxt 知识点

    脚手架工具 create-nuxt-app 创建项目: $ npx create-nuxt-app <项目名> 启动项目: To get started: cd nuxt_demo npm ...

  10. 20180414模拟赛T1——BEAD

    BEAD 源程序名 BEAD.???(PAS,C,CPP) 可执行文件名 BEAD.EXE 输入文件名 BEAD.IN 输出文件名 BEAD.OUT 时间限制 1S 内存限制 128MB 有n颗形状和 ...