【发布时间】:2018-06-03 13:53:08
【问题描述】:
我今天一直在修改 passport-jwt,试图弄清楚如何在我的应用程序中正确设置它。我在注册用户和保存 jwt 令牌时没有遇到任何问题,但我认为我没有使用护照这样做。现在我正在尝试登录用户,但我总是收到错误Error: Failed to serialize user into session。我在下面的一些文章中看到过:
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
但我似乎找不到任何示例,甚至找不到说明在哪里使用这些的护照文档的配置部分。这可能是我问题的根源,但我不确定。我发现令人困惑的 Passport 方面之一是 JWT 提取器。如果我只想将我的护照转换为 jwt 令牌并将其保存在我的 mongo 数据库中,为什么我需要它们中的任何一个(即使它们是必需的)?自己使用jsonwebtoken 并根据需要对字符串进行哈希/取消哈希处理并使用cookie-parser 创建我自己的会话而不是使用像Passport 这样的东西不是更容易吗?我也尝试在我的休息电话中使用 passport.authencate() 但那些返回 401。您可以在登录调用下方看到失败的尝试被注释掉。
请帮忙,我觉得我是唯一一个发现护照比不那么健壮的东西更复杂的人,但我真的致力于解决它!
import express from 'express';
import path from 'path';
import bodyParser from 'body-parser';
import connection from './database';
import jwt from 'jsonwebtoken';
import cors from 'cors';
import crypto from 'crypto';
import passport from "passport";
import passportJWT from "passport-jwt";
const JwtStrategy = passportJWT.Strategy;
const ExtractJwt = passportJWT.ExtractJwt;
import { User } from './schema';
import { read } from 'fs';
const app = express();
const corsOptions = {
origin: '*',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(cors(corsOptions));
app.use(passport.initialize());
app.use(passport.session());
const jwtOptions = {
jwtFromRequest: ExtractJwt.fromBodyField('Password'),
secretOrKey: 'secretKey',
jsonWebTokenOptions: { expiresIn: 172800 }
}
passport.use(new JwtStrategy(jwtOptions, (jwt_payload, done) => {
User.findOne({ password: jwt_payload.sub }, (err, user) => {
user ? done(null, user) : done(null, false);
});
}));
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.post('/test', (req, res) => {
console.log('Success');
console.log(req.body);
res.json(req.body);
});
app.post('/register', async (req, res) => {
if (req.body.FirstName
&& req.body.LastName
&& req.body.Email
&& req.body.Password
) {
const token = await jwt.sign(
{ Password: req.body.Password },
jwtOptions.secretOrKey,
{ expiresIn: '48h' }
);
const CreatedAt = await Date.now();
const newUser = await new User({
FirstName: req.body.FirstName,
LastName: req.body.LastName,
Email: req.body.Email,
Password: token,
});
await newUser.save(err => {
err ? console.log(err) : res.json(newUser);
});
}
throw new('error');
});
// app.post('/login', passport.authenticate('jwt', { session: false }),
// (req, res) => {
// console.log(req.user)
// if (req.body.Email && req.body.Password) {
// User.findOne({ Email: req.body.Email }, (err, user) => {
// if (err) return console.log(err);
// console.log(user);
// return user;
// }).then((res) => {
// jwt.verify(res.Password, jwtOptions.secretOrKey, (err, decoded) => {
// err ? console.log(err) :
// req.login(decoded, (err) => {
// // if (err) { return next(err); };
// if (err) {
// console.log(err)
// } else {
// console.log(decoded)
// }
// });
// });
// }).catch(err => console.log('Failed ', err));
// } else {
// console.log(req.body);
// }
// });
app.post('/login', (req, res) => {
if (req.body.Email && req.body.Password) {
User.findOne({ Email: req.body.Email }, (err, user) => {
if (err) return console.log(err);
console.log(user);
return user;
}).then((res) => {
// res.password returns the jwt string successfully
jwt.verify(res.Password, jwtOptions.secretOrKey, (err, decoded) => {
err ? console.log(err) :
req.login(decoded, (err) => {
// if (err) { return next(err); };
if (err) {
console.log(err) // always returns the error posted above
} else {
console.log(decoded)
}
});
});
}).catch(err => console.log('Failed ', err));
} else {
console.log(req.body);
}
});
app.listen(9000, () => {
console.log(`Listening on port 9000`);
});
自定义提取器尝试
const customExtractor = req => {
User.findOne({ Email: req.body.Email }, '_id', (err, user) => {
const token = jwt.sign(
{ id: user },
'secretKey',
{ expiresIn: '48h' }
);
return token;
});
根据@OrthoHomeDefense 的帖子,我创建了以下内容并成功向客户端发送了一个 jwt 令牌:
app.post("/login", (req, res) => {
if (req.body.Email && req.body.Password) {
User.findOne({ Email: req.body.Email }, (err, user) => {
if(user.Password === req.body.Password) {
console.log()
var token = jwt.sign(JSON.stringify(user), jwtOptions.secretOrKey);
res.json({token: token});
} else {
console.log(err);
res.status(401).json({message:"Passwords did not match."});
}
});
} else {
res.status(401).json({message:"Please provide an email and a password."});
}
});
【问题讨论】:
-
你看过这个吗? jonathanmh.com/…
-
@OrthoHomeDefense 我之前已经通读过它,看起来我被困在 Passport JWT 策略部分,因为我收到了 401。我不明白的部分是提取器本身。为什么我会从任何规定的提取器位置收到 jwt? jwt 不是曾经是提供密码的散列字符串吗?在这种情况下,我不是从数据库中接收 jwt,而不是任何提取器位置吗?我知道我说的肯定是错的,但我似乎不知道怎么做?
-
你能告诉我你在客户端调用请求时的样子吗?
-
POST localhost:9000/login 401 (Unauthorized) index.js:13 错误:在 XMLHttpRequest 的结算 (settle.js:18) 处的 createError (createError.js:16) 请求失败,状态码为 401。处理负载(xhr.js:77)
-
您的“承载”标头是什么样的?
标签: javascript express authentication jwt passport.js