skip to Main Content

I have SpringBoot 2.0.0.M7 project where I am using WebSession with Redis (org.springframework.session:spring-session-data-redis:2.0.0.RELEASE).

I have a WebFlux route which supposed to do redirect to eBay with the eBay session id. Every time user is visiting that route I need to request different session id from eBay API and include it into the redirect URL. Later, eBay will redirect user back to my application where I need that session id to request token.

During testing I saw that that value of the session attribute (in my case it’s ebay_session_id) can’t be replaced with the new value when browser still have a cookie with the existing session ID. In the route where I am requesting again ebay_session_id I am getting old value and not the new one.

The code which store SessionID is following:

return ebayApiReactiveWrapper
        .getSessionId(apiContext)
        .flatMap(sessionId ->
            request
                .session()
                .map(webSession -> {
                    webSession
                        .getAttributes()
                        .put("ebay_session_id", sessionId);

                    return sessionId;
                })
        )
        .flatMap(sessionId -> {
            final UriBuilder uriBuilder = uriBuilderFactory.uriString(
                ebayApiSettings.getSignInUrl()
            );

            uriBuilder.queryParam("runame", ebaySettings.getRuName());
            uriBuilder.queryParam("SessID", sessionId);

            return ServerResponse.temporaryRedirect(redirectUri).build();
        });

I tried to add webSession.save() after put method but it doesn’t help.

What I am doing wrong? Thank you in advance!

UPDATE

Some new details about what is happening with the session data in Redis. When session is created (empty Redis) the data looks like that:

127.0.0.1:6379> hkeys "spring:session:sessions:cbbf8000-6ce8-4238-a427-9aab37d2702b"
1) "lastAccessedTime"
2) "maxInactiveInterval"
3) "creationTime"
4) "sessionAttr:ebay_session_id"

When I visit same route second time (session cookie still exists and the session data is still in Redis) the data is changing:

127.0.0.1:6379> hkeys "spring:session:sessions:cbbf8000-6ce8-4238-a427-9aab37d2702b"
1) "sessionAttr:ebay_session_id"

Through, sessionAttr:ebay_session_id still contains value from the first request.

The worst thing is that such structure cause NullPointerException when another route is trying to get session data. Looks like it expecting other 3 fields to be presented and fails when it’s not the case.

2

Answers


  1. Chosen as BEST ANSWER

    Looks like not many people faced such issue. I found my solution to solve it.

    I saw that session will not be updated if the attribute set of the session is not changed. So I am adding a new attribute every time I need to update session value. My first flatMap from the question code is changed the following way:

    .flatMap(sessionId ->
        request
            .session()
            .map(webSession -> {
                // we need to check if session already started before applying "hack"
                if (webSession.isStarted()) {
                    // "hack"
                    final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yMdkmsn");
                    webSession
                        .getAttributes()
                        .put(LocalDateTime.now().format(dateTimeFormatter),"1");
                }
    
                webSession
                    .getAttributes()
                    .put("ebay_session_id", sessionId);
    
                return sessionId;
            })
    )
    

    When new attribute is added session considered as changed and will be updated in redis.


  2. I faced that problem and used almost the same hack, but just by updating a primitive typed session attribute.

    For example:

    webSession.getAttributes().put("userContext", userContext);
    
    webSession.getAttributes().put("lastContextUpdateTime", System.currentTimeMillis());
    

    This avoids to add a new attribute for each session update, but triggers the mutable object update in Redis too.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search