【问题标题】:Spring Boot session attribute is null in REST controllerREST 控制器中的 Spring Boot 会话属性为空
【发布时间】: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


【解决方案1】:

首先 - 请在两种控制器方法中检查您的sessionid,它们必须相同。如果不是,那么显然你有一个新会话,这意味着它上面没有“twitter”属性。

第二次 - 您的请求之间可能有一段时间(在第一个获取令牌的请求和第二个获取令牌之间),这可能导致会话终止并生成一个新的'没有“twitter”属性了,所以请检查你的会话超时。

【讨论】:

    猜你喜欢
    • 2019-12-28
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多