IT

여러 사용자 계정을 병합하기위한 아키텍처

lottoking 2020. 5. 24. 11:19
반응형

여러 사용자 계정을 병합하기위한 아키텍처


알았어, 내가 등록하고 로그인 할 수있는 웹 사이트가있어 페이스 북, 트위터 또는 링크 인 계정으로 로그인 할 수도 있습니다.

사용자는 하나의 계정 만 등록해야합니다. 어떻게 든 다른 방법으로 로그인하는 사용자 계정을 병합하고 싶습니다. 이것을 해결하는 가장 좋은 해결책은 무엇입니까?

예를 들어, 사용자는 자신의 Facebook 계정으로 로그인합니다. 데이터를 사용하여 계정을 자동으로 등록합니다. 웹 사이트의 사용자 이름과 비밀번호를 이메일로 보내야합니까? (Facebook의 정책에 문제가없는 경우). 사용자 이름과 비밀번호를 입력 할 수있는 두 번째 화면을 제공해야합니까? 그러나 그것은 페이스 북 계정으로 로그인하는 아이디어가 아닙니다. 참여 절차를 단순화해야합니다.

사용자가 우리 웹 사이트에 등록하고 다음에 트위터 계정으로 로그인 할 수도 있습니다. 이 두 계정을 하나로 병합하려면 어떻게해야합니까? 가장 좋은 방법은 무엇입니까?

그래서 기본적으로 내 질문은 : 사용자가 우리 웹 사이트의 회원이되는 4 가지 방법이 있습니다. 사용자가 여러 가지 방법을 사용하기로 결정한 경우이 4 가지 방법을 모두 하나의 계정 만 만들려면 어떻게해야합니까? 사용자 자신에게 번거롭지 않게하는 가장 좋은 방법은 무엇입니까?


편집하다:

이 질문을한지 3 년 후, 나는 일련의 기사를 통해 스스로 답을하고있다 : http://www.sitepoint.com/series/using-social-networks-as-a-login-system/


나는 현재 똑같은 일에 직면하고 있습니다. 내가 디자인 한 디자인은 다소 간단하지만 잘 작동합니다.

핵심 아이디어는 로컬 사이트 아이덴티티 및 타사 사이트 아이덴티티의 모델은 격리 된 상태로 유지하지만 나중에 연결되는 것입니다. 따라서 사이트에 로그인하는 모든 사용자는 여러 타사 사이트 ID에 매핑되는 로컬 ID를 갖습니다.

로컬 ID 레코드에는 최소한의 정보가 포함되어 있습니다. 단일 키일 수도 있습니다. 기본 키일뿐입니다. (응용 프로그램의 경우 사용자의 이메일, 이름 또는 생년월일은 신경 쓰지 않습니다.이 계정에 로그인 한 사람인지 알고 싶습니다.)

타사 ID에는 타사 인증과 관련된 정보 만 포함됩니다. OAuth의 경우 이는 일반적으로 사용자 식별자 (ID, 이메일 또는 사용자 이름 등)와 서비스 식별자 (인증 된 사이트 또는 서비스를 나타내는)를 의미합니다. 응용 프로그램의 다른 부분에서는 데이터베이스 외부에서 해당 서비스 식별자가 해당 서비스에서 관련 사용자 식별자를 검색하는 방법과 쌍을 이루어 인증이 수행되는 방식입니다. OpenID의 경우 인증 방법이 더 일반화된다는 점을 제외하고 동일한 접근 방식을 사용합니다 (다른 ID URL을 사용하고 서비스 식별자 인 경우를 제외하고는 거의 항상 동일한 프로토콜을 수행 할 수 있기 때문에).

마지막으로, 어떤 타사 ID가 어떤 로컬 ID와 연결되어 있는지 기록합니다. 이러한 레코드를 생성하기 위해 흐름은 다음과 같습니다.

  • 사용자가 타사 ID를 사용하여 처음으로 로그인합니다. 로컬 신원 레코드가 생성 된 다음 타사의 신원 레코드가 생성 된 다음 쌍이됩니다.
  • 제어판에서 사용자는 타사 서비스에 로그인하여 계정을 연결할 수 있습니다. (이것이 어떻게 작동하는지 매우 간단합니다.)
  • 사용자가 무심코 여러 계정을 만드는 시나리오에서 솔루션은 매우 간단합니다. 사용자가 계정 중 하나에 로그인 한 상태에서는 이전에 제어판 기능을 통해 이전에 사이트에 로그인 할 때 사용한 다른 계정에 로그인합니다. 웹 서비스는이 충돌을 감지하고 (로그인 한 사용자의 로컬 ID가 방금 로그인 한 타사 ID에 연결된 로컬 ID와 다르므로) 사용자에게 계정 병합 메시지가 표시됩니다.

계정 병합은 로컬 ID의 각 개별 필드 (응용 프로그램마다 다를 수 있으며 로컬 ID 레코드에 몇 개의 필드 만있는 경우 쉬워야 함)를 병합 한 다음 연결된 타사 ID를 확인하는 것입니다. 결과 로컬 신원에 연결됩니다.


이메일기반으로하는 많은 사이트 가 중복되는 결합 요인 으로 발견되는 경향이 있습니다.

이것이 가능한 옵션이라는 것을 알 수 있지만 병합 방법에 대한 선호도에 달려 있습니다. 이메일 주소는 사람들이 비밀번호 변경, 서비스 종료, 계정 잔액 부족 등과 같이 사이트에서 중요한 정보 변경을 확인하는 데 주로 사용하는 방법입니다. 웹의 사회 보장 번호 시스템과 거의 비슷하지만 통신 기능이 있습니다. . 문화적으로 : 전자 메일은 OAuth 인증 서비스에서 매우 고유 한 ID라고 가정하는 것이 합리적이라고 생각합니다. 물론 Facebook과 Google의 로그인 양식이 요구하는 것입니다.

나의 현재 생각 과정.

로그인 페이지에는 3 가지 옵션이 있습니다

  • 자신의 사이트 멤버십
  • 페이스 북으로 로그인
  • Google로 로그인

1) 처음으로 사용자 로그인 : 계정이 생성되고 처음으로 채워지는 등록 흐름을 트리거합니다.

 if the user logins using Facebook (or whatever 3rd party login)
      1) call the Facebook api asking for their information (email, name, etc...) 
      2) create an account membership entry in your database somewhat like this 

         Table = Users
         [ UserId   |       Email             | Password ]
         [    23     | "newuser@coolmail.com" |  *null*  ]

      3) create an external auths entry like so
         *ProviderUserId is the unique id of that user on the provider's site

         Table = ExternalAuths
         [ ExternalAuthId  |  User_UserId   | ProviderName |   ProviderUserId  ]
         [    56           |      23        |   Facebook   |  "max.alexander.9"]

 if the user wants to create an account with your own registration it would just be this           

         Table = Users
         [ UserId   |       Email           |   Password  ]
         [    23     | newuser@coolmail.com |  myCoolPwd  ]

2) 다른 시간에 사용자가 돌아 왔지만 Google 로그인을 클릭하기로 결정했습니다.

      1) call the Google api asking for their information (email, name, etc...) 

      2) once you get the email, match it up to the userId entry with the existing email 

      3) create an additional External auth entry as such

         Table = ExternalAuths
         [ ExternalAuthId  |  User_UserId   | ProviderName |   ProviderUserId  ]
         [    56           |      23        |   Facebook   |  "max.alexander.9"]
         [    57           |      23        |    Google    |  "1234854368"     ]

3) 이제 데이터베이스 항목의 전자 메일을 신뢰하는 계정을 외부 로그인에서 신뢰하는 계정과 병합했습니다.

후속 로그인의 경우

외부 로그인을 먼저하고 나중에 사용자가 나중에 비밀번호로 로그인 할 수있게하려면 어떻게해야합니까?

이 작업을 수행하는 두 가지 쉬운 방법이 있습니다

  • 외부 인증에서 계정을 만들 때 처음 로그인 할 때 응용 프로그램에 처음으로 입력 할 수 있도록 암호를 요청하십시오.

  • If they already have registered using facebook or google first then somehow wanted to register using your own site's registration form. Detect if the email address that they entered already exists, ask them for a password, and send them an email confirmation after the registration is complete.


I've gone through this with sled.com. There are multiple issues here with regard to creating accounts and supporting multiple third-party accounts for login. Some of them are:

  • Do you need to support both a local password and third-party logins?

For sled.com, I've decided to drop local password due to the small value it adds and the additional cost in securing a password entry form. There are many known attacks for breaking passwords and if you are going to introduce passwords you must make sure they are not easy to break. You also need to store them in a one-way-hash or something similar to prevent them from being leaked.

  • How much flexibility do you want to allow in supporting multiple third-party accounts?

It sounds like you already chose the three login providers: Facebook, Twitter, and LinkedIn. That's great because it means you are using OAuth and working with a well-defined set of trusted providers. I'm no fan of OpenID. The remaining question is if you need to support multiple third-party accounts from the same provider (e.g. one local account with two Twitter accounts linked). I'm assuming no, but if you do, you will need to accommodate that in your data model.

For Sled, we support login with Facebook, Twitter, and Yahoo! and within each user account store a key for each one: { "_id":"djdjd99dj", "yahoo":"dj39djdj",twitter:"3723828732","facebook":"12837287"}. We setup a bunch of constrains to ensure that each third-party account can only be linked to a single local account.

If you are going to allow multiple accounts from the same third-party provider you will need to use lists or other structures to support that, and with that, all the other restrictions to ensure uniqueness.

  • How to link multiple accounts?

The first time the user signs-up for your service, they first go to the third party provider and come back with a verified third-party id. You then create a local account for them and collect whatever other information you want. We collect their email address and also ask them to pick a local username (we try to pre-populate the form with their existing username from the other provider). Having some form of local identifier (email, username) is very important for account recovery later.

The server knows this is a first time login if the browser does not have a session cookie (valid or expired) for an existing account, and that the third-party account used is not found. We try to inform the user that they are not just logging-in, but are creating a new account so that if they already have an account, they will hopefully pause and login with their existing account instead.

We use the exact same flow to link additional accounts, but when the user comes back from the third party, the presence of a valid session cookie is used to differentiate between an attempt to link a new account to a login action. We only allow one third-party account of each type and if there is already one linked, block the action. It should not be a problem because the interface to link a new account is disabled if you already have one (per provider), but just in case.

  • How to merge accounts?

If a user tried to link a new third-party account which is already linked to a local account, you simply prompt them to confirm they want to merge the two accounts (assuming you can handle such a merge with your data set - often easier said than done). You can also provide them with a special button to request a merge but in practice, all they are doing is linking another account.

This is a pretty simple state machine. The user comes back from the third-party with a third-party account id. Your database can be in one of three states:

  1. The account is linked to a local account and no session cookie is present --> Login
  2. The account is linked to a local account and a session cookie is present --> Merge
  3. The account is not linked to a local account and no session cookie is present --> Signup
  4. The account is not linked to a local account and a session cookie is present --> Linking Additional account

    • How to perform account recovery with third-party providers?

This is still experimental territory. I have not seen a perfect UX for this as most services provide both a local password next to the third-party accounts and therefore focus on the "forgot my password" use case, not everything else that can go wrong.

With Sled, we've opted to use "Need help signing in?" and when you click, ask the user for their email or username. We look it up and if we find a matching account, email that user a link which can automatically log them into the service (good for one time). Once in, we take them directly to the account linking page, tell them they should take a look and potentially link additional accounts, and show them the third-party accounts they already have linked.


Both approaches for auto merging accounts leaves a pretty big vulnerability that would allow someone to take over an account. They both seem to make the assumption that the user is who they say they are when they offer the merge option to a registering user.

My recommendation for mitigating the vulnerability is to request the user authenticate with one of the known Identity Providers prior to performing the merge to verify the identity of the user.

Example: User A registers with Facebook identity. Sometime later they go back to your site and attempt to access with Windows Live ID and start the registration process. Your site will prompt User A with... It looks like you have registered with Facebook previously. Please login with Facebook (provide link) and we can merge your Windows Live ID with your existing profile.

Another alternative is to store a shared secret(password/personal question) on the initial registration that the user must provide when merging identities, however this gets you back into the business of storing shared secrets. It also means you have to handle the scenario where the user does not remember the shared secret and the workflow that goes along with it.


Most of the posts are quite old and I guess Google's free Firebase Authentication service wasn't yet around. After verifying with OAuth, you pass the OAuth token to it and get a unique user id which you can store for reference. Supported providers are Google, Facebook, Twitter, GitHub and there is an option to register custom and anonymous providers.


Great answers and resources above. My contribution is summarised here... https://github.com/JavascriptMick/learntree.org/blob/master/design/Schema.md

TLDR: seperate Account and Person schemas. 2 variants of Account, Email and OAuth.

Account -authenticates-> Person


You should allow login from one account, then when logged in give the option to add different other account to merge with it.

참고URL : https://stackoverflow.com/questions/6666267/architecture-for-merging-multiple-user-accounts-together

반응형