我正在用Spring编写一些简单的页面,并希望将一些数据添加到会话持续存在的对象中。它似乎坚持GET请求,但不适用于那些使用POST方法的请求。
我有一个UserData组件如下:
package com.mycompany.controllers.components;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("session")
public class UserData {
private boolean loggedIn;
public UserData() {
loggedIn = false;
}
public boolean isLoggedIn() {
return loggedIn;
}
public void setLoggedIn(boolean loggedIn) {
this.loggedIn = loggedIn;
}
}
我有一个控制器如下:
package com.mycompany.controllers;
...
@RestController
@Scope("session")
public class DefaultController {
@Autowired
UserData userData;
...
@GetMapping("/")
public ResponseEntity index() {
printUserData(userData);
ResponseEntity entity;
if((entity = authenticate(userData)) != null) {
return entity;
}
...
}
@GetMapping("/setloggedIn")
public ResponseEntity setLoggedIn() {
printUserData(userData);
userData.setLoggedIn(true);
}
@PostMapping("/logIn" )
public ResponseEntity logIn(@RequestBody LogInDTO dto) {
printUserData(userData);
...
userData.setLoggedIn(true);
}
protected static void printUserData(UserData user) {
if(user== null) {
LOG.info("UserData is null");
return;
}
LOG.info("UserData logged in: {}", user.isLoggedIn());
}
}
当我导航到" /" UserData.isLoggedIn()
的输出按预期为假。
当我向" / logIn"发出请求时输出,再次如预期,是错误的。在进行一些参数验证之后,调用方法UserData.setLoggedIn(true)
,但导航到" /"输出仍然是假的。
当我导航到" / setLoggedIn"然后,loggedIn最初为false,但这也将loggedIn设置为true,现在所有请求都是" /"或" / setLoggedIn"结果输出为true。
对" / logIn"的进一步POST请求输出假
我错过了什么或这是正常行为吗?
更新1
当我检查GET请求的会话ID时,我可以看到它等于我的cookie中存储的JSESSIONID。我看到每个POST请求都有不同的会话ID。
所以问题是,我如何发送JSESSIONID以及POST请求。我目前正按以下方式执行请求:
fetch('/logIn', {
method: 'POST',
body: JSON.stringify({
username: txtUsername.value,
password: txtPassword.value
}),
headers : {
'Content-Type' : 'application/json'
}
})
.then(result => {
result.text().then(function(text) {
if(result.status == 200) {
location.reload();
} else {
alert("Error:\n" + text);
}
});
})
.catch(e => {
console.log(e);
alert("Error:\n" + e);
});
更新2
我发现JSESSIONID cookie是HttpOnly并且不能被JavaScript读取,这可能是因为它没有发送POST请求吗?导致servlet每次都创建一个新会话。
答案 0 :(得分:0)
fetch命令需要“”凭据:'include'“设置为true。这允许使用post请求发送仅http cookie,因此服务器能够解析当前会话。工作获取代码看起来像这样:
fetch('/logIn', {
method: 'POST',
body: JSON.stringify({
username: txtUsername.value,
password: txtPassword.value
}),
credentials: 'include', // <<< FIX
headers : {
'Content-Type' : 'application/json'
}
})
.then(result => {
result.text().then(function(text) {
if(result.status == 200) {
location.reload();
} else {
alert("Error:\n" + text);
}
});
})
.catch(e => {
console.log(e);
alert("Error:\n" + e);
});