@FunC
2018-03-26T11:09:31.000000Z
字数 1866
阅读 5426
JavaScript
passport.js 是用来实现 authenticate/authorize 的中间件。
鉴于官网文档里都是一些代码片段,没有 API 的详细说明,这里整理一些需要注意的点。
passport.initialize() 初始化 passport.js 的配置。如果需要持久化的登陆session,还需要调用中间件 passport.session() 。中间件的顺序应为:express-session -> passport.initialize -> passport.sessionpassport.serializeUser() 和 passport.deserializeUser() (作用见下文)passport.authenticate() 的路由主要参考自 http://toon.io/understanding-passportjs-authentication-flow/
以在路由 /login 上进行认证为例
1. 用户 POST 一个登陆表单,导致中间件 passport.authenticate 的执行
2. 调用相应的认证策略,这里因为是用 username 和 password 进行登陆,所以使用 local 策略(由npm packagepassport-local 提供)
3. Passport 获取 req.body.username 和 req.body.password ,用作验证策略的参数(需要提前配置 body-parser )
4. 从数据库取出相应的 user 对象,验证密码
5. 如果验证通过,passport 内部自动调用 req.login() ,用于建立登陆session。
6. req.login() 会调用我们先前定义的 passport.serializeUser() ,该方法决定将 user 实例的哪些数据存入 session,一般选择存 user.id。passport.serializeUser() 将设置 req.session.passpot.user = {/* serialized user object */}
7. 然后将 user 实例挂载到 req.user 上
8. 之后执行常规的 requestHandler
通过认证之后,发来的请求会经过下面的步骤:
1. Express 加载 session 的数据,并将其挂载在 req上。
2. 先前配置的 passport.initialize 中间件会发现 session 中有 passport.user 的数据。如果没有则创建一个 req.passport.user = {}
3. 随后触发 passport.session 中间件,它本质上是一个名为 “session” 的认证策略,通过 session 存储的 user data,根据先前定义的 passport.deserializeUser 方法,从数据库中取出相应的 user 实例,并重新挂载在 ·req.user` 上
passport.authenticate('local') 方法的核心是从 req.body 中获取用户名和密码,并进行验证。所以只能用在 POST 请求上req.isAuthenticated(),而不是调用passport.authenticate() 方法passport.user 的数据,但是 req.user 为 undefined,passport.deserializeUser() 方法没有被调用的情况: express-session, passport.initialize(), passport.session() 三个中间件的顺序cookie.secure 设为 false,否则通过 HTTP 请求时 passport.deserializeUser() 会没有被调用req.logIn() 没有被调用。如果在调用 passport.authenticate(‘local’, custtomCallback) 时使用了自定义的回调函数,需要手动调用 req.logIn()