在Passport.js中禁用会话
在普通的Web应用程序中,用于验证用户身份的凭据仅在登录请求期间传输。成功验证后,Passport会建立一个持久的登录会话。该会话通过用户浏览器中的cookie进行维护。
然而,在某些情况下,不需要会话支持。例如,API服务器需要每个请求都提供凭证进行身份验证。在这种情况下,您可以禁用会话支持。需要将session选项设置为false。
app.post('/auth',
passport.authenticate('local-signin', {
successRedirect : '/dashboard',
failureRedirect : '/login',
session: false
})
)
或者,可以提供自定义的回调函数,让应用程序处理成功或失败。
app.get('/auth', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
// your logic to how you serve your user
})(req, res, next);
});
在上面的示例中,passport.authenticate()从路由处理程序中调用,而不是作为路由中间件使用。这样可以通过闭包使回调函数可以访问req和res对象以及next方法。
示例: 在典型的Web应用程序中,用户在注册后将重定向到登录页面。因此,我们不需要在新注册时创建会话。让我们看看实施。
项目设置: 创建一个新的Node.js项目,命名为 Auth 。
mkdir Auth && cd Auth
npm init -y
安装依赖项:
- 我们可以使用body-parser中间件来解析请求体。
npm i express body-parser
- 我们可以使用任何模板引擎,我们的案例中是ejs。
npm i ejs
- 我们可以使用uuid模块来创建唯一的用户ID。
npm i uuid
- 我们不直接存储用户输入的密码,而是存储用户密码的哈希值。我们可以使用bcrypt模块生成密码的哈希值。
npm i bcrypt
- 我们需要安装passport模块以使用其功能。
npm i passport
- Passport提供了许多策略,我们将使用passport-local策略。
npm i passport-local
项目结构: 它将如下所示。
- passport-config.js: 这是护照配置文件。
- register.ejs: 这是注册页面的视图。
- index.js: 这是主服务器设置文件。
register.ejs
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container{
position: relative;
width: 400px;
padding: 8px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
box-shadow: black 0 0 14px 8px;
}
label{
font-size: 17px;
display: block;
}
input{
display: block;
margin: 4px;
padding: 4px 8px;
height: 31px;
width: 350px;
font-size: 22px;
}
.btn-submit{
border-radius: 2px;
padding: 10px 17px;
background-color: green;
border: none;
color: white;
font-weight: bold;
cursor: pointer;
width: 120px;
height: 44px;
}
.btn-submit:hover{
opacity: 0.8;
}
.brand{
text-align: center;
color: #c2bfbf;
}
</style>
</head>
<body>
<div class="container">
<h1 class="brand">GeeksForGeeks</h1>
<h2>Register</h2>
<form action="/register" method="POST">
<label for="email">Email: </label>
<input id="userEmail" name="email" type="email">
<label for="password">Password: </label>
<input id="userPassword" name="password" type="password">
<input class="btn-submit" type="submit" value="Register">
</form>
</div>
</body>
</html>
passport-config.js
const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')
const { v4: uuid } = require('uuid')
const initialize = (passport, getUserByEmail, save) => {
// Verify callback function implementation
const register = async (email, password, done) => {
// Check whether user is already registered or not
const user = getUserByEmail(email)
// If user is registered, invoke done()
if (user != null)
return done(null, user, {
message: "You are already registered" })
// Generate user password's hash
const hashedPassword = await bcrypt.hash(password, 10)
// Create new user
const newUser = {
// Generate user id
id: uuid(),
email: email,
password: hashedPassword
}
// Save newly created user to database
save(newUser)
// Invoke done()
return done(null, newUser, {
message: "Registration Successful" })
}
// Middleware
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
}, register))
}
module.exports = initialize
index.js
// Import Modules
const express = require('express')
const bodyParser = require('body-parser')
const passport = require('passport')
const ejs = require('ejs')
const intializePassport = require('./config/passport-config')
const app = express()
const port = 8080
// Dummy in-memory user database
const Users = []
// Returns middleware that only parses urlencoded bodies
// A new body object contained pasrse data add to the
// request object
app.use( bodyParser.urlencoded( { extended: false } ) )
// Pass require logic
intializePassport(
passport,
email => Users.find(user => user.email === email),
user => Users.push(user)
)
// Set EJS as view engine
app.set('view engine', 'ejs')
// API endpoint
app.get('/', (req, res)=> res.render('register.ejs'))
app.post('/register', (req, res, next)=> {
// Invoke implementation of local strategy
passport.authenticate('local-signup',
(err, user, info)=>{
// If any error
if (err)
res
.status(500)
.send("<H1> Server Error! </H1>")
else{
// Display the user object
console.log({
Error: err,
User: user,
Message: info.message
})
// Send message to user
res.send(`<H1> { info.message } <H1>`)
}
// Pass req, res, and next as closure
})(req, res, next)
})
// Start server
app.listen(port, () => console.log(`Server listening on port{port}!`))
运行应用的步骤: 使用以下命令运行index.js文件:
node index.js
输出: 我们将在终端屏幕上看到以下输出。
Server listening on port 8080
现在打开任何浏览器并转到 http://localhost:8080/, 我们将看到以下输出:
提交表单后,我们将在浏览器上看到 注册成功 同时也在终端屏幕上看到以下输出: