Announcement Announcement Module
No announcement yet.
Considering only allowing one userid per providerid ? (pk change?) Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Considering only allowing one userid per providerid ? (pk change?)

    I see how it's possible you could associate multiples of the same provider type (eg multiple Facebook accounts) to the same user account. (For sake of discussion forward using Facebook as the example provider)

    Currently it looks like the initial Facebook account you associate would be the "primary" one since it would get the rank of 1. Future ones, if you did allow them to 'connect', look like they'd increment the rank to a consecutive higher number so the only way to change your primary connection would be to "disconnect" which would call removeConnections.

    I like what the Social Showcase does and the examples where it creates a Facebook bean based on the primary connection that can be injected into controllers etc.

    But what would happen in the following scenario:
    • User connects to the app for the first time with FacebookAccountA.
    • User logs out of the app and logs into Facebook with FacebookAccountB.
    • User now manually logs into the main app using his username and password that was also a username that was associated with FacebookAccountA in the UsersConnection table.
    • Developer provides a "Connect To Facebook" button on the page and the user clicks it to connect. The user would be connected, but it wouldn't be the primary connection so things could get ugly if you relied on the injection of a Facebook bean like the examples show based on a primary connection.

    Now, granted I 'think' this last scenario would be unlikely since I believe the developer would typically only be showing a "Connect" button if there wasn't already an existing Facebook account associated. (eg connectionRepository.findConnections("facebook").s ize() > 0 ) BUT I'm beginning to think maybe the datamodel should enforce this explicitly? Especially when you consider that a 'remove connection' actually goes and wipes all connections for a provider (it doesn't just remove one of them.) Why not maybe just change things so there is a unique constraint on just userid and providerid, instead of also including providerUserId:

    CONSTRAINT userConnection_pk PRIMARY KEY (userId, providerId, providerUserId))

    change to

    CONSTRAINT userConnection_pk PRIMARY KEY (userId, providerId))

    This of course would mean you could only associate one provider with your account at any given time, but I'm thinking this might be ok and would make things a lot easier to deal with.

  • #2
    Just bumping this because I am curious still about it. I'm starting to think even the pk should be:

    CONSTRAINT userConnection_pk PRIMARY KEY (providerUserId, providerId))

    Do we really want to allow different user logins to be associated with the same providerUserId (eg same facebook account)?

    This creates a problem on signin since you'll get an error about multiple userids returned for a facebook connection. I tend to think the datamodel should possibly enforce this? Again, this would rarely show up in the UI since you typically wouldn't show a "connect" button if the user already had a connection (however, if by accident which happened in my case in development you did show a "connect" button at all times, there isn't anything in the api preventing you from associating a different user with the same providerUserId - which is problematic. I'm thinking the insert should throw an error if such an attempt is made?


    • #3
      I'll grant you that in the context of Facebook this lack of constraint doesn't make much sense, but in the grander scope of all that Spring Social integrates with, it is there for a purpose:

      Suppose that you have a marketing department of 2-3 people, all of which have the responsibility and ability to post to Twitter on behalf of their company's Twitter identity. If Spring Social limited it to 1 app user per Twitter user, then it'd be quite limiting. Spring Social couldn't be used to build an app that published tweets for those users unless they all shared a common signin to the app.

      Even so, if you want to enforce it in the schema, you're welcome to tweak JdbcUsersConnectionRepository.sql however you see fit. Nothing in Spring Social ever directly references that file, aside from some tests and the example code. Spring Social's wants that table to exist with that table and column names, but aside from that, you're welcome to customize it for your app's needs. Even then, Spring Social doesn't tie you to that schema...You could choose to write your own implementation of UsersConnectionRepository and come up with any schema you like.


      • #4
        I agree that would be a nice to have (multiple users tied to a single providerUserId.) To accomplish that though I think the ProviderSigninController and JdbcUsersConnectionRepository will need some tweaking. Right now the handleSignIn of ProviderSigninController makes a a call:

        private RedirectView handleSignIn(Connection<?> connection, NativeWebRequest request) {
        		String userId = usersConnectionRepository.findUserIdWithConnection(connection);
        Which I believe will throw an error (in cases of multiple users tied to the same providerUserId) since that will call queryForObject and would return multiple rows.

        Maybe the answer is to have another post redirect url: "postSignInWhenMultipleUsersUrl" that would represent a jsp "Please select the account you want to join with."

        handleSignIn could then change to make a call to a method of JdbcUsersConnectionRepository: findUserIdsWithConnection that would change a bit from the existing:

        public String findUserIdWithConnection(Connection<?> connection)


        public List<String> findUserIdsWithConnection(Connection<?> connection)

        Then in handleSignIn if the list size is 1, you handle with the normal postSignInUrl, if greater than 1 you redirect to the multipleUsersPostUrl ?