热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在express框架下使用passport实现验证(0)。

前面2个文章说明了cookiesession保存、验证用户的方法都有各自的缺点。现在推荐一个使用passport的方法验证用户。这里的代码是基于上一遍文章(express框架下使用

前面2个文章说明了COOKIE/session保存、验证用户的方法都有各自的缺点。现在推荐一个使用passport的方法验证用户。
这里的代码是基于上一遍文章(express框架下使用session)的代码。
关于passport的学习差不多一个月了,还是有搞不清的地方,不过可以正常简单使用完成登录、验证、登出功能。passport的笔记分为2部分。基本使用方法和使用jwt.

基本使用方法。

这部分目的在于说清passport的工作过程。

  1. 安装依赖。

npm i passport passport-local passport-local-mongoose

  1. 在app.js中挂载并配置passport

// app.js
var passport = require('passport')
var authenticate = require('authenticate')
// 在app.use(session())后
app.use(passport.initialize())
app.use(passport.session())
// authenticate.js
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('./models/user')
passport.use(new LocalStrategy(User.authenticate())) // passport.use(new LocalStrategy()) 是配置验证策略。User.authenticate是plm为user添加的静态方法,用来验证用户的。可是它返回了什么?
passport.serializeUser(User.serializeUser()) // plm提供的静态方法。passport.serializeUser()为了建立持续的session必须序列化session.再在后序的请求中反序列化。
passport.deserializeUser(User.deserializeUser()) // plm提供的静态方法

  1. 在models/user.js中使用passport-local-mogoose(plm)

var mOngoose= require('mongoose'),
Schema = mongoose.Schema,
passportLocalMOngoose= require('passport-local-mongoose'),
User = new Schema({
admin: {
type: Boolean,
default: false
}
})
User.plugin(passportLocalMongoose)
module.exports = mongoose.model('User', User)

  1. 在routes/users.js中使用plm的注册、验证方法。

router.post('/signup', (req, res, next) => {
console.log(req.body)
User.register(new User({username: req.body.username}),
req.body.password,
(err, user) => {
if (err) {
res.statusCode = 500,
res.json({err: err})
} else {
passport.authenticate('local')(req, res, () => {
res.statusCode = 200
res.json({success: true, status: 'registration successful!'})
})
}
})
})
router.post('/login', passport.authenticate('local'), (req, res) => {
res.statusCode = 200
res.json({success: true, status: 'you are successful logged in!'})
})
router.get('/logout', (req, res, next) => {
if (req.session) {
req.session.destroy()
res.clearCOOKIE('session-id')
res.send('登出成功。重定向的事让前端做')
} else {
var err = new Error('you are not logged in!')
err.status = 403
next(err)
}
})

  1. 登录后才能访问的页面

// app.js
// 先写不需要登录的路由
// app.use('/router0', router0)
// 这是验证是否登录的中间件.
app.use((req, res, next) => {
if (req.isAuthenticated()) {
next()
} else {
// 返回相应信息
res.send('请登录后访问.')
// 也可以重定向到登录页面
// res.redirect('/login')
// 也可以进入错误页面.
// res.redirect('/error')
}
})
// 再写需要登录的路由
// app.use('/router1', router1)

回顾上面的例子。主要做了

  1. 安装、引入。
  2. 配置。
  3. 登录时使用策略验证。
  4. 为需要登录后才能访问的页面使用验证.

在npm上passport的文档。

策略

passport就是为验证请求而生的。它有好多验证策略。可以使用本地验证策略,可以使用委托验证,可以使用openID验证。
在使用验证前都需要配置passport.下面是配置的demo

passport.use(new LocalStrategy(authcb))

session

passport会维持登录session.为了使用session一直工作,所以验证用户时必须序列化,再在后续的请求的反序列化。
passport不会暴露任何如何保存用户记录的方法。所以需要程序员提供序列化和反序列化逻辑。下面是一个例子,保存时序列化了用户id,取时根据反序列化的用户id找到user.

passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(null, user.id)
})
})

中间件

若在express/connect应用中使用要passport,则需要挂载passport.initialize()中间件。
若使用持续session.(建议但不强制),则挂载passport.session()中间件。

app.use(session())
app.use(passport.initialize()) // 这两个方式到底做了什么,还需要去看原码。
app.use(passport.session())

验证请求

passport提供了一个在路由中验证请求的方法——authenticate()

app.post('/login', passport.authenticate('local', {failureRedirect: '/login'}), (req, res) => {
res.redirect('/')
} )

passport的方法

use([strategyName, ]strategy)绑定需要使用的策略。
initiallize()返回初始化passport的中间件。
session()返回使用session的中间件。
serializeUser(fn)序列化后保存到session里。
deserializeUser(fn)从session里取数据时反序列化。
authenticate(strategyName, options, fn)进行验证。

passport为req添加的方法

初始化时添加的。

别名
logIn(user, options, cb)login()登录
logOut()logout()
isAuthenticated()当前用户是否登录。
isUnauthenticated()当前用户是否没登录。

passport 基本使用方法

初始化:app.use(passport.initialize());
安装策略: passport.use(new BasicStrategy(…))
使用策略:app.get(‘/…’, passport.authenticate(‘basic’),(req,res)=>{…})
其他方便函数:
req.user 登陆后存在
req.login() 仅在注册时手工调用。登陆时由策略自动调用。
req.logout() 登出时调用

无session的,如basic-auth,在每次使用时都要检查

app.get('/api/users/me',
passport.authenticate('basic', { session: false }),
function(req, res) {
res.json({ id: req.user.id, username: req.user.username });
});

有session的,在第一次由策略得到user。之后每次由sessionid对应的session得到user。

策略=>user 又分为2步
web数据=>策略参数
策略参数=>user

sessiOnid=>user 也包含2件事
serializeUser: user=>sessionid
deserializeUser: sessiOnid=>user


推荐阅读
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • “你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬” ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 本文介绍了在wepy中运用小顺序页面受权的计划,包含了用户点击作废后的从新受权计划。 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 微信民众号商城/小顺序商城开源项目介绍及使用教程
    本文介绍了一个基于WeiPHP5.0开发的微信民众号商城/小顺序商城的开源项目,包括前端和后端的目录结构,以及所使用的技术栈。同时提供了项目的运行和打包方法,并分享了一些调试和开发经验。最后还附上了在线预览和GitHub商城源码的链接,以及加入前端交流QQ群的方式。 ... [详细]
  • loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ... [详细]
author-avatar
铁匠他夫人_738
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有