【发布时间】:2020-01-24 07:36:22
【问题描述】:
我正在开发一个使用 Spring Boot 2.2.2 的社交 Twitter 应用程序。我正在按照https://careydevelopment.us/2017/05/24/implement-twitter-login-solution-spring-boot/ 此处的说明进行操作。
我刚刚修改了我的代码,使其更加面向 REST,而不是 RedirectView(如上面的链接中所做的那样)
@PostMapping("/getToken")
public ResponseEntity<TwitterTokenResponse> getToken(HttpServletRequest request) throws Exception {
Twitter twitter = getTwitter();
String callbackUrl = "http://localhost:3000/settings";
RequestToken requestToken = twitter.getOAuthRequestToken(callbackUrl);
request.getSession().setAttribute("requestToken", requestToken);
*//setting twitter attribute in session*
request.getSession().setAttribute("twitter", twitter);
String twitterUrl = requestToken.getAuthorizationURL();
TwitterTokenResponse twitterTokenResponse = new TwitterTokenResponse(requestToken.getToken(), requestToken.getTokenSecret(), true, 0L, null);
log.info("Authorization url is " + twitterUrl);
log.info("Request token is " + requestToken);
return ResponseEntity.ok(twitterTokenResponse);
}
@PostMapping("/twitterCallback")
public ResponseEntity<TwitterTokenResponse> twitterCallback(@RequestParam(value = "oauth_verifier", required = false) String oauthVerifier, @RequestParam(value = "denied", required = false) String denied, HttpServletRequest request) throws Exception {
if (denied != null) {
log.error("Could not get token from Twitter! Access denied");
return null;
}
*//Getting twitter attribute back from session but it is null*
Twitter twitter = (Twitter) request.getSession().getAttribute("twitter");
RequestToken requestToken = (RequestToken) request.getSession().getAttribute("requestToken");
AccessToken token = twitter.getOAuthAccessToken(requestToken, oauthVerifier);
request.getSession().removeAttribute("requestToken");
TwitterTokenResponse twitterTokenResponse = new TwitterTokenResponse(token.getToken(), token.getTokenSecret(), true, token.getUserId(), token.getScreenName());
log.info("Access token is " + token);
return ResponseEntity.ok(twitterTokenResponse);
}
从 getToken() 方法中可以看出,我在会话中设置 twitter 变量,并尝试在 twitterCallback() 方法中从会话中获取相同的变量。我从会话中获得的 twitter 属性总是为空。有什么原因会这样吗?有什么办法可以解决这个问题?
谢谢
【问题讨论】:
-
你检查了两个州的 sessionid 吗?我的意思是在getToken中查看sessionid,然后在twitterCallback中查看,请确保它们是相同的。
-
嗨@MehrdadHosseinNejad,确实两个会话中的会话ID不同。我将会话超时修复为 spring.session.timeout=30m 但它仍然无法正常工作。
-
所以显然你的问题是因为在两个不同的请求中有两个不同的会话。 (会话在两个请求中必须相同)。你在你的应用中使用 Spring Security 吗?
-
嗨,是的,我正在使用 Spring Security,目前会话创建策略是无状态的。我也用 IF_REQUIRED 尝试过,但也没有用。我正在使用 JWT 来保护其余端点
-
如果你使用 JWT,这意味着你的服务器不能保持状态。 (它必须是无状态的),但是您通过为会话设置属性使其有状态,这根本没有任何意义。我建议您将 twitter 令牌保存到客户端 JWT,而不是会话。 (保持你的服务器无状态)
标签: spring spring-boot session