React 应用程序 + API 身份验证
React Application + API authentication
我已经设置了一个 API 来访问我的后端,并实施了 express sessions 来验证用户。
当使用 Postman 登录,然后访问受保护的 GET 请求时,它工作正常。
但是我正在构建的 React SPA 似乎无法在登录后使用 session 来验证自己。
我尝试了很多在网上找到的建议(更改 CORS headers,在 React 中使用显式 cookie 设置,更改我存储 sessions 的方式,...)但是 none 似乎解决了这个问题。
我会尝试包含相关的代码片段:
Server-side(休息API)
Session & CORS 中间件:
//Session Middleware
api.use(session({
genid: (req) => {
console.log('Inside session middleware');
console.log(req.sessionID)
return uuid()
},
cookie: {
maxAge: 60000
},
secret:"123",
resave:false,
saveUninitialized:true,
store: new MongoStore({
mongooseConnection:db,
clear_interval: 3600
})
}));
// CORS
api.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true")
next();
})
登录功能&护照认证:
exports.login = (req,res,next) => {
passport.authenticate('local',(err,user,info) =>{
//... (login handling)
})(req,res,next);
}
// Passport Middleware
passport.use(new LocalStrategy(
(username, password, done) => {
Promotor.findOne({username:username,password:password}, (err,user) =>{
if (err) {
done(err,null);
}
if (!user){
done(null,false,{message:'Invalid Credentials!'})
} else {
done(null,user)
}
});
}
));
// Passport serializing
passport.serializeUser((user,done) => {
done(null,user._id);
});
passport.deserializeUser((id,done) => {
Promotor.findById(id,function(err,user){
if(err){
done(err,false);
} else {
done(null,user);
}
})
})
受保护的 GET 函数
(isAuthenticated() Returns 在我的 SPA 中使用 axios 时为 false)
exports.getNameById = (req,res) => {
console.log(req.session)
console.log(req._passport)
if(!req.isAuthenticated()){ //RETURNS FALSE IN REACT & TRUE IN POSTMAN
return res.status(401).send();
}
return controller.getDocumentById(Promotor,'firstname lastname',req,res);
}
Client-side(反应 SPA)
Axios 请求登录
(适用于 Postman 和应用程序,并正确创建 session)
handleSubmit(e){
console.log("Trying To log in");
axios
.post(`${api_url}/promotor/login`,{username: this.state.username, password:this.state.password})
.then( (res) => {
if (res.status === 200) {
console.log(res);
this.setState(() => ({toClientHome: true, id:res.data.id}));
}
});
e.preventDefault();
}
axios请求访问受保护的GET请求
(当设置了 session cookie 时,GET 请求在邮递员中有效,但在 axios 中无效)
getFullName(id) {
axios
.get(`${api_url}/promotor/name/${id}`,{
withCredentials: true
})
.then((res) => {
//... rest of the code
});
}
能否请您将 cors 中间件代码放在文件的顶部(在所有导入之后)!!
api.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true")
next();
})
然后再试一次。
我已经设置了一个 API 来访问我的后端,并实施了 express sessions 来验证用户。
当使用 Postman 登录,然后访问受保护的 GET 请求时,它工作正常。
但是我正在构建的 React SPA 似乎无法在登录后使用 session 来验证自己。
我尝试了很多在网上找到的建议(更改 CORS headers,在 React 中使用显式 cookie 设置,更改我存储 sessions 的方式,...)但是 none 似乎解决了这个问题。
我会尝试包含相关的代码片段:
Server-side(休息API)
Session & CORS 中间件:
//Session Middleware
api.use(session({
genid: (req) => {
console.log('Inside session middleware');
console.log(req.sessionID)
return uuid()
},
cookie: {
maxAge: 60000
},
secret:"123",
resave:false,
saveUninitialized:true,
store: new MongoStore({
mongooseConnection:db,
clear_interval: 3600
})
}));
// CORS
api.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true")
next();
})
登录功能&护照认证:
exports.login = (req,res,next) => {
passport.authenticate('local',(err,user,info) =>{
//... (login handling)
})(req,res,next);
}
// Passport Middleware
passport.use(new LocalStrategy(
(username, password, done) => {
Promotor.findOne({username:username,password:password}, (err,user) =>{
if (err) {
done(err,null);
}
if (!user){
done(null,false,{message:'Invalid Credentials!'})
} else {
done(null,user)
}
});
}
));
// Passport serializing
passport.serializeUser((user,done) => {
done(null,user._id);
});
passport.deserializeUser((id,done) => {
Promotor.findById(id,function(err,user){
if(err){
done(err,false);
} else {
done(null,user);
}
})
})
受保护的 GET 函数
(isAuthenticated() Returns 在我的 SPA 中使用 axios 时为 false)
exports.getNameById = (req,res) => {
console.log(req.session)
console.log(req._passport)
if(!req.isAuthenticated()){ //RETURNS FALSE IN REACT & TRUE IN POSTMAN
return res.status(401).send();
}
return controller.getDocumentById(Promotor,'firstname lastname',req,res);
}
Client-side(反应 SPA)
Axios 请求登录
(适用于 Postman 和应用程序,并正确创建 session)
handleSubmit(e){
console.log("Trying To log in");
axios
.post(`${api_url}/promotor/login`,{username: this.state.username, password:this.state.password})
.then( (res) => {
if (res.status === 200) {
console.log(res);
this.setState(() => ({toClientHome: true, id:res.data.id}));
}
});
e.preventDefault();
}
axios请求访问受保护的GET请求
(当设置了 session cookie 时,GET 请求在邮递员中有效,但在 axios 中无效)
getFullName(id) {
axios
.get(`${api_url}/promotor/name/${id}`,{
withCredentials: true
})
.then((res) => {
//... rest of the code
});
}
能否请您将 cors 中间件代码放在文件的顶部(在所有导入之后)!!
api.use(function(req,res,next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true")
next();
})
然后再试一次。