当前位置: 首页 > 后端技术 > Node.js

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

时间:2023-04-03 11:12:08 Node.js

前两篇文章说明cookie/session存储和用户认证方式各有不足。现在建议使用通行证方法对用户进行身份验证。这里的代码是基于上一篇文章的代码(使用express框架下的session)。学习passport快一个月了,还有一些不清楚的地方,但是可以正常使用,简单的完成登录、验证、注销等功能。护照笔记分为两部分。基本使用方法和usingjwt.basic使用方法。这部分的目的是阐明护照的工作过程。安装依赖项。npmipassportpassport-localpassport-local-mongoose在app.js中挂载和配置passport//app.jsvarpassport=require('passport')varauthenticate=require('authenticate')//在app.use(session())afterapp.use(passport.initialize())app.use(passport.session())//authenticate.jsvarpassport=require('passport'),LocalStrategy=require('passport-local').Strategy,User=require('./models/user')passport.use(newLocalStrategy(User.authenticate()))//passport.use(newLocalStrategy())是配置认证策略。User.authenticate是plm为user添加的静态方法,用于对用户进行身份验证。但是它返回什么?passport.serializeUser(User.serializeUser())//plm提供的静态方法。passport.serializeUser()必须序列化会话以建立持久会话,然后在后续请求中反序列化它。passport.deserializeUser(User.deserializeUser())//plm提供的静态方法使用models/user.js中的passport-local-mogoose(plm)varmongoose=require('mongoose'),Schema=mongoose.Schema,passportLocalMongoose=require('passport-local-mongoose'),User=newSchema({admin:{type:Boolean,default:false}})User.plugin(passportLocalMongoose)module.exports=mongoose.model('User',用户)在routes/users.js中使用plm的注册和验证方式。router.post('/signup',(req,res,next)=>{console.log(req.body)User.register(newUser({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=200res.json({success:true,status:'注册成功!'})})}})})router.post('/login',passport.authenticate('local'),(req,res)=>{res.statusCode=200res.json({success:true,status:'你登录成功!'})})router.get('/logout',(req,res,next)=>{if(req.session){req.session.destroy()res.clearCookie('session-id')res.send('登录成功。让前端做重定向')}else{varerr=newError('你还没有登录!')err.status=403next(err)}})登录后才能访问的页面//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)查看上面的示例。主要是安装和介绍。配置。在登录时使用策略身份验证。对需要登录的页面使用身份验证。npm上的护照文件。保单护照是为认证请求而生的。它有很多认证策略。可以使用本地认证策略,可以使用委托认证,也可以使用openID认证。在使用身份验证之前需要配置Passport。下面是配置的demopassport.use(newLocalStrategy(authcb))sessionpassport会维护登录会话。为了使用session一直工作,必须在认证用户的时候序列化,然后在后续请求的响应中序列化。Passport没有公开任何关于如何保存用户记录的方法。所以程序员需要提供序列化和反序列化逻辑。下面是一个例子,保存时将用户id序列化,根据反序列化的用户找到user.passport.serializeUser((user,done)=>{done(null,user.id)})passport.deserializeUseridwhenfetching((id,done)=>{User.findById(id,(err,user)=>{done(null,user.id)})})如果中间件用于express/connectapplication和passport是必需的,它需要挂载passport.initialize()中间件。如果你使用持久会话。(推荐但非强制),挂载passport.session()中间件。app.use(session())app.use(passport.initialize())//这两个方法是做什么的,需要看原代码。app.use(passport.session())AuthenticateRequestPassport提供了一种方法来验证路由中的请求-authenticate()app.post('/login',passport.authenticate('local',{failureRedirect:'/login'}),(req,res)=>{res.redirect('/')})passport的方法use([strategyName,]strategy)绑定要使用的策略。initialize()返回初始化护照的中间件。session()返回使用会话的中间件。serializeUser(fn)被序列化并存储在会话中。deserializeUser(fn)在从会话中获取数据时反序列化。authenticate(strategyName,options,fn)进行身份验证。Passport是在req添加的方法初始化的时候添加的。AliaslogIn(user,options,cb)login()logout()logout()isAuthenticated()当前用户是否登录。isUnauthenticated()当前用户是否未登录。Passport基本用法初始化:app.use(passport.initialize());安装策略:passport.use(newBasicStrategy(...))使用策略: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});});如果有会话,则第一次从策略中获取用户。之后每次从sessionid对应的session中获取user。Strategy=>user分为2步webdata=>strategy参数strategy参数=>usersessionid=>user还包含2个东西serializeUser:user=>sessioniddeserializeUser:sessionid=>user