Announcement Announcement Module
Collapse
No announcement yet.
In memory Connection repository Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • In memory Connection repository

    Hi all,

    I have a grails app which is using JdbcUsersConnectionRepository for storing connection. It was fine in development as I was using in-memory database.

    I know we can use pre defined script for actual databases. I was wondering whether there is an option having this in memory even in production?

    User connection is very specific to session, then why are we persisting it in database? I am not sure whether user connections are deleted after session expires.

    Thanks,
    Abhijith

  • #2
    A connection and a session are two different things. A connection is essentially a relationship between a user, an app, and some API...that connection's primary data point is the OAuth access token that was granted during connection time.

    In OAuth 1.0/1.0a access tokens don't expire (at least not per the spec) and are valid until the user explicitly revokes the authorization (conceptually, forever). Therefore, a Spring Social connection for an OAuth 1.0/1.0a provider is also long-lived. In OAuth 2, authorizations are long-lived, but tokens are allowed to expire and thus are considered short-lived. Even so, a so-called "short-lived" token may last for a very long time. Facebook tokens, for example, have a 60-day expiration.

    If you were to use an in-memory implementation, that'd be fine until you restart your app. Then suddenly all of those tokens are forgotten and then your users are forced to reauthorize. Depending on the provider, the user may not even notice that reauthorization is taking place, but in many cases they'll have to authorize your app again and it may confuse them or frustrate them. Persisting connections in a database ensures that those connections survive a server restart.

    Also, if your app has a *LOT* of users, then an in-memory connection repository will have higher demands on memory-usage (obviously).

    That said, I like the idea of an in-memory repo for development-time purposes. It's not on my todo list currently, but feel free to open a JIRA issue requesting it or (better yet) implement one yourself and submit a pull request.

    Comment


    • #3
      Hi

      In terms of having an in-memory repo for development-time purposes, this was something I needed a while back so I created my own InMemoryUsersConnectionRepository implementation. It's just a simple map-based implementation and may have thread-safety issues, but for development it seems to do the job:

      https://github.com/michaellavelle/sp...epository.java

      I also created a quickstart version which extends this implementation for a different project which is a work in progress. The quickstart version is designed for even simpler development-time use where a single development session key can be passed into the constructor for a given provider and user:

      https://github.com/socialsignin/soci...epository.java

      Both implementations have been tested with the AbstractUsersConnectionRepositoryTest and seem to behave as expected, but work may be needed to tighten up the code.

      Hope this helps,

      Michael

      Comment


      • #4
        Thanks Criag, makes total sense.

        I was wondering what would happen when you bring spring security in the midst. Because spring security authentication tokens would anyways be destroyed when you restart the server. Those tokens are not persisted.

        If spring security forces you to reauthenticate, does Spring social pull the data from DB?

        @Michael - thanks, it is really helpful.

        Thanks,
        Abhijith

        Comment


        • #5
          Well, with Spring Security (setting Spring Social aside for a moment), the user still has to authenticate back into the app, but they don't have to re-register for the app...at least not in the typical case. Their user data is still persisted in a DB somewhere (unless you're using the in-memory user service, which is not recommended for typical production use). So, while a server restart may require the user to reauthenticate, the user's identity is still stored in a DB and ready to use.

          Back to Spring Social: The connection ties that user data (not the currently authenticated user), the application, and the API together. Sure, when the connection is initially created, it is created for the currently authenticated user, but the connection is linked to the user's record in the DB. If the user logs out (or if the server is shutdown), the connection still exists. When they signin again, their connection will still be there and ready to go (assuming that the connection is stashed in a DB and not in memory).

          Comment


          • #6
            Hmm....I was under the impression that after user explicitly logs out or after session time out, I need to call 'disconnect' which would essentially delete user connection record from DB.

            In what circumstances user connection data live beyond session?

            Thanks,
            Abhijith

            Comment


            • #7
              There's no reason to think that a user connection wouldn't live beyond a session--in fact, I'd think that's commonly the case. A connection tied to a user via that user's ID, not the session. So even if a user signs out, then the connection should still exist. When they sign back into your application and assuming that they still have the same user ID, then that connection should still be usable (unless the access token has been expired or if they explicitly revoked the authorization).

              The only reason I'd think that to not be the case is if your user only exists for the duration of their session. If the user ceases to exist (in the DB, of course...I suspect there'd be some serious liability issues if the actual user disappeared after using your app :-) ) after signing out, then it wouldn't make sense to keep their connection records around. But in most applications, the user's identity remains beyond any session--so there's no need to ditch their connections when they signout or the session expires.

              Comment


              • #8
                I have a question related to this discussion.

                Imagine an application where no local users exists. This app has no need to store any user data.
                But the app provides functionality to connect with Twitter or Facebook to display information about the logged in user.

                I wonder what the best setup would be for such an app.
                While looking at the example code the ConnectController would my best fit. It hooks up with the ConnectionsRepository via the UserConnectionsRepository which is linked via a "local" user id.
                As I don't need this I was also thinking of SessionConnectionsRepository implementation. Would this make sense or am I on the wrong track?

                Comment


                • #9
                  ConnectController attempts to create a connection between a local user and their account on the provider. Since you don't have a local user, that's not what you want.

                  What you want is something akin to what's in the spring-social-quickstart app where no local user DB is maintained (aside from a cookie that keeps track of the user once they are signed in). The only thing the app knows about the user is what is given to them from Facebook after signing in with Facebook. It does this through the ProviderSignInController.

                  Have a look at that sample and let me know if you have any questions about how it captures user data from FB.

                  Comment


                  • #10
                    Hi Craig

                    I had a look at the spring-social-quickstart app at https://github.com/SpringSource/spri...ial-quickstart but in SocialConfig I see the following bean definition:

                    Code:
                    @Bean
                    public UsersConnectionRepository usersConnectionRepository() {
                        JdbcUsersConnectionRepository repository = new JdbcUsersConnectionRepository(dataSource, 
                            connectionFactoryLocator(), Encryptors.noOpText());
                        repository.setConnectionSignUp(new SimpleConnectionSignUp());
                        return repository;
                    }
                    It's using a JdbUsersConnectionRepository which would indicate it's trying to retrieve and store user connections from a database?
                    Or am I wrong?

                    Comment


                    • #11
                      While looking at code of ConnectController and ProviderSignInController they both seem to be tight to UsersConnectionRepository.
                      As I only need to sign in with Facebook/Client (and not storing any information itself) I think I'm better of creating my own Controller? Or would you advise differently?

                      Comment


                      • #12
                        You're right that both are tied to UsersConnectionRepository and that even during the course of an implicit signup (as is demonstrated in the quickstart), a connection is saved to the connection table. But you still don't need a local user database...just a database to hold those connections.

                        Even then, I probably wouldn't write a custom controller. Instead, I'd consider writing a custom connection repository pair. It's important that ProviderSignInController know about those connections or else it will force a signin again the next time they visit your app. Maybe that's what you want...in which case, the custom connection repository could store nothing and always report that it can't find a connection.

                        But your point is well-taken that there needs to be an example or better guidance on writing apps that don't maintain any sort of local database and only rely on the provider for all user data. I'll add that to my list of examples to put together. Of course, I welcome anyone else who might want to contribute such an example.

                        Comment


                        • #13
                          Yes I was also thinking of writing custom connection pair as well.

                          One question related to the quickstart sample is that I'm wondering if there would be a benefit storing the connections in the database without a local user?
                          It probably means the user can be connected automatically when he/she tries wants to connect at the same provider, right? Thus without having to accept access to the application again.
                          If this is right it would make sense to store the connection indeed.

                          Comment

                          Working...
                          X