我正在用Flutter开发一个应用程序。在登录过程中,我正在检索数据。其想法是将此数据存储在该高速缓存中,并在以后用于其他操作。我使用nodejs,mongodb作为后端,flutter作为前端。我想在登录过程中检索专业化列表。一旦用户登录,就会创建令牌,并将userId、电子邮件和令牌等信息存储在cookie中。然后,我有一个中间件verifyAccessToken,它检查cookie中的令牌是否可用,如果检查正确,则API getSpecialization返回可用的专业化列表。我面临的问题是,我在flutter中的登录APIservice中包含getSpecialization,但我无法检索列表,因为verifyAccessToken中间件被绕过,导致403错误。任何帮助将不胜感激。下面是我的后端和前端代码:
Nodejs登录:
const authService = require("../../../services/authService");
exports.login = async (req, res, next) => {
const { email, password } = req.body;
console.log("login req body is ", req.body);
//simple checker for username and password
if (!email || !password) {
return res.status(400).json({ message: "email or password is missing" });
}
try {
//get the data from our auth service
const { user, validPassword, token, maxAge } = await authService.loginUser(email, password)
//check if the user exists
if (!user) {
return res.status(401).json({
message: "Login not successful",
error: "User not found",
});
}
//return error if the password is incorrect
if (!validPassword) {
return res.status(401).json({
message: "Login not successful",
error: "Password is incorrect",
});
}
res.cookie("email", user.email, {
httpOnly: true,
maxAge: maxAge * 1000, // convert 2h to ms; maxAge uses milliseconds
});
res.cookie("userId", user._id,{
httpOnly: true,
maxAge: maxAge * 1000, // convert 2h to ms; maxAge uses milliseconds
});
//send our cookie with the token
res.cookie("jwt", token, {
httpOnly: true,
maxAge: maxAge * 1000, //convert 2h to ms; maxAge uses miliseconds
});
//if everything is good return the user
return res.status(200).json({
message: "Login successful",
user,
});
} catch (err) {
res.status(401).json({
message: "Login not successful",
error: err.message,
});
}
};
verifyAccessToken:
const jwt = require("jsonwebtoken");
require("dotenv").config();
//this only works if you use cookie-parser
const checkCookie = (req) => {
console.log('inside checkCookie')
console.log('all our cookies are: ', req.cookies)
//we get the jwt cookie we need
return req.cookies['jwt']
}
//middleware for verifying the JWT
const verifyAccessToken = (req, res, next) => {
//define token
let token;
//authenticate through Bearer token
if (req.headers.authorization && req.headers.authorization.startsWith("Bearer ")) {
token = req.headers.authorization.split(' ')[1]
//logs so you see what's happening
console.log('auth bearer token')
console.log({ token })
}
else {
token = req.headers["x-access-token"] || checkCookie(req) || null
//logs
console.log('our token is from x-access-token header, a cookie or null')
console.log({ token })
}
//if we can't get our token anywhere then the response is an error
if (!token) {
return res.status(403).send("A token is required for authentication");
}
try {
//we use the JWT library to verify the token
//and we need to know the token_key which we encrypted our information
const decoded = jwt.verify(token, process.env.TOKEN_KEY);
//log
console.log({ decoded })
//the middleware adds the user information to the request and sends it to the route
req.user = decoded;
} catch (err) {
return res.status(401).send("Invalid Token");
}
//if you have doubts check Express middleware docs: http://expressjs.com/en/guide/using-middleware.html
return next();
};
module.exports = verifyAccessToken;
getSpecialization:
const {Specialization} = require('../../../models/specialization')
exports.getSpecialization = async (req, res) => {
try {
const specializzazioni = await Specialization.find({}, { _id: 0, __v: 0 }); // Escludi _id e __v dalla risposta
res.json(specializzazioni);
} catch (error) {
console.error('Errore durante il recupero delle specializzazioni:', error);
res.status(500).json({ message: 'Errore durante il recupero delle specializzazioni' });
}
};
路线
router.route("/login").post(login);
//router.use(verifyAccessToken);
router.use(verifyAccessToken);
router.route("/book").post(book);
router.route("/getbooking/:id").get(getBooking);
router.route("/logout").get(logout);
router.route("/getSpecialization").get(getSpecialization);
Flutter登录APIService
static Future<bool> login(LoginRequestModel model) async {
Map<String, String> requestHeaders = {
'Content-Type': 'application/json',
};
var url = Uri.http(Config.apiUrl, Config.loginAPI);
var response = await client.post(url,
headers: requestHeaders,
body: jsonEncode(model.toJson())
);
if (response.statusCode == 200) {
// Settare i dettagli del login
await SharedService.setLoginDetails(loginResponseJson(response.body));
// Ottenere il valore del cookie 'set-cookie' dalla risposta
String? setCookie = response.headers['set-cookie'];
if (setCookie != null) {
// Estrarre il valore del token dal cookie
String? token = parseCookieValue(setCookie);
print (token);
if (token != null) {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('jwt', token);
}
}
await getSpecializations();
return true;
} else {
return false;
}
}
getSpecialization
static Future<List<Specialization>> getSpecializations() async {
var url = Uri.http(Config.apiUrl, Config.getSpecializaionAPI);
var response = await client.get(url);
if (response.statusCode == 200) {
// Converte la risposta JSON in una lista di oggetti Specialization
List<dynamic> jsonList = jsonDecode(response.body);
List<Specialization> specializations = jsonList
.map((item) => Specialization(
specId: item['specId'],
description: item['description'],
))
.toList();
return specializations;
} else {
return []; // o gestisci l'errore in base alle tue esigenze
}
}
2条答案
按热度按时间m0rkklqb1#
注1:
通过flutter获取数据并存储该高速缓存中
示例:
注2:
然后我有一个中间件verifyAccessToken,它可以检查cookie中的令牌是否可用
注3:
刷新访问令牌
示例:
j5fpnvbx2#
您面临的问题是
getSpecialization
API端点受verifyAccessToken
中间件保护,但当您从Flutter登录过程调用它时,中间件被绕过,导致403错误。要解决这个问题,您需要确保身份验证令牌与请求沿着发送到
getSpecialization
端点。以下是如何修改Flutter代码以包含令牌:1.在Flutter登录APIService中修改
getSpecializations
方法,如下所示:1.确保您已导入Flutter所需的包:
通过将
Authorization
标头与从共享首选项中检索到的令牌一起包含在其中,可以确保将令牌与请求沿着发送到后端,从而允许verifyAccessToken
中间件正确地对请求进行身份验证。请注意,此解决方案假定您已经实现了登录过程,并将令牌存储在共享首选项中。如果您还没有实现它,请确保在成功登录后将令牌存储在共享首选项中。
通过这些修改,您应该能够在登录过程之后检索专门化列表,而不会遇到403错误。