什么是 PassportJS?如何集成它?
根据官方定义:
Passport 是 Node.js 的身份验证中间件。
Passport 具有极高的灵活性和模块化特性,可以毫不突兀地集成到任何基于 Express 的 Web 应用程序中。
一套全面的策略支持使用用户名和密码、Facebook、Twitter 等进行身份验证。
基本上,PassportJS 为我们管理会话用户,并为我们提供了在应用程序中集成登录/注册选项时可以使用的许多策略。
我们来看看如何将其整合起来。
集成 PassportJS
让我们从应用程序的基础架构开始:
const express = require('express')
const app = express()
const port = 3000
app.listen(port, () => console.log(`App listening on port ${port}!`))
现在我们可以开始配置Passport了。
我们需要配置会话中间件、cookie解析器和body解析器:
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser')
const expressSession = require('express-session')
const passport = require('passport')
...
app.use(cookieParser()) // 1
app.use(bodyParser.json()) // 2
app.use(bodyParser.urlencoded({
extended: true,
})) // 3
app.use(expressSession({
secret: '5om35ecr37',
resave: false,
saveUninitialized: false,
})) // 4
app.use(passport.initialize()) // 5
app.use(passport.session()) // 6
让我们来看一下并解释每一行代码的作用:
- 中间件解析 Cookie 标头值,并将 cookies 属性添加到请求对象中,该请求对象包含所有按 cookie 名称键分组的 cookie。
- 将请求体解析为 JSON 数据,并将其添加到请求对象的 body 属性中。
- 增加了对解析 URL 格式请求体的支持。
- 用于生成会话 cookie 并将其与服务器端存储的数据(即已登录用户)进行匹配的中间件。
- 初始化 Passport 核心,该核心运行并管理策略。
- 添加对会话中用户数据管理的支持。
增加本地化策略
现在中间件都配置好了,我们可以向应用程序中添加策略了。
在这种情况下,这将是一项本地化策略。
首先,我们需要安装选定的策略:
npm install passport-local
或者:
yarn add passport-local
现在我们可以进行配置了。
为了简化本教程,我将在回调函数中返回静态用户对象:
const userStore = {
findByUsername: () => ({
id: 1,
name: 'Test User',
username: 'testuser',
validatePassword: () => true
})
}
passport.use(new LocalStrategy(
(username, password, done) => {
const user = userStore.findByUsername(username)
// User does not exist in our database or password was invalid
if (!user || !user.validatePassword(password)) {
return done(null, false)
}
// If user was found and password is valid we can return user object
// in callback
return done(null, user)
}
))
就这样!
我们的登录表单逻辑已准备就绪。
会话序列化和反序列化
当我们使用Passport并启用会话支持时,我们必须实现两个回调函数,Passport 将使用这两个回调函数来序列化和反序列化用户。
当用户被保存到会话中时,将调用 Serialize 回调函数。
我们将使用用户 ID,以便稍后在数据库中找到该用户。
passport.serializeUser((user, done) => {
done(null, user.id)
})
反序列化回调用于根据存储在 cookie 中的数据在数据库中查找用户。
在本例中,存储在 cookie 中的数据是用户 ID。
const userStore = {
...,
findUserById: userId => ({
id: 1,
name: 'Test User',
username: 'testuser',
validatePassword: () => true
})
}
passport.deserializeUser((userId, done) => {
// Find user in database by id from session
const user = userStore.findUserById(userId)
// If user was not found throw an error
if (!user) {
done('unathorized')
return
}
// If user was found return it via callback, this user object will be
// available in request object as user property
done(null, user)
})
添加登录表单
现在我们可以给应用添加登录表单了。
为此,我们来定义一个简单的HTML表单。
<html>
<head>
<title>Awesome login form</title>
</head>
<body>
<form action="/" method="POST">
<label for="username">
Username:
</label>
<input name="username" id="username" />
<label for="password">
Password:
</label>
<input type="password" name="password" id="password" />
<button type="submit">
Login
</button>
</form>
</body>
</html>
并将此 HTML 文件返回到我们应用程序的根 URL:
const path = require('path')
app.get('/', (request, response) => {
response.sendFile(path.resolve('./login.html'))
})
现在我们需要定义处理表单 POST 请求的路径:
// This will print “Logged in!” text after successful login
app.post(
'/',
passport.authenticate('local'),
(request, response) => {
response.send('Logged in!')
}
)
让我们回到根 URL 处理程序,如果用户已登录,则返回不同的视图。
首先,我们需要为登录视图创建 HTML 文件:
<html>
<head>
<title>Awesome logged in view</title>
</head>
<body>
<a href='/logout'>Logout</a>
</body>
</html>
并将我们的根 URL 处理程序修改如下:
// This will redirect user back to root url after logging in
app.post('/', passport.authenticate('local', { successRedirect: '/' }))
app.get('/', (request, response) => {
const viewPath = request.isAuthenticated()
? './loggedIn.html'
: './login.html'
response.sendFile(path.resolve(viewPath))
})
如您所见,我在登录视图中定义了“/logout”URL,因此我们也必须处理该URL。
点击此链接将注销用户并将其重定向回登录表单。
app.get('/logout', (request, response) => {
request.logOut()
response.redirect('/')
})
概括
如果你使用NodeJS,PassportJS是一个很棒的身份验证工具,你可以轻松地针对不同的策略进行定制。
请告诉我你的想法!
文章来源:https://dev.to/pagepro_agency/what-is-passportjs-and-how-to-integrate-it-31io