Representing and persisting Users (who login with username and password AND social logins) in a database (MySQL)

StackOverflow https://stackoverflow.com/questions/22162446

Pergunta

I am using Play Framework (v2.2.x), SecureSocial (v2.1.3) and scala (v2.10) to create a login template for play apps. I want the login template to support both social logins (Twitter, Facebook, Github etc.) and UsernamePassword login. I am having a difficult time representing both kinds of Users (Social and Local) for persistence.

I am using MySQL(v 5.6.x) as my database and squeryl (v0.9.6) as the ORM for persistence.

I need some help in modeling both SocialUser and LocalUser (users authenticating using username and password) for persistence.

I have looked at https://github.com/jaliss/securesocial/tree/master/samples/scala/demo. I have that demo running (with additional set up for mysql and squeryl. Also, extended that example to work with Facebook and Github).

I have not written any code yet, but I was planning to model as follows:

User Class:

+-------------------+---------------+------------+---------------+-------------+-------------+-----------+
| provider_user_id  | providerType  |    email   |   avatarUrl   | passwordInfo| oauth1Info  | oauth2Info|
+-------------------+---------------+------------+---------------+-------------+-------------+-----------+

AuthProviderForUser:

+-------------------+----------------------+--------------+
| provider_user_id  | application_user_id  | providerType |
+-------------------+----------------------+--------------+

Token class:

+------+--------+---------------+-----------------+-----------+------------+
| uuid |  email |  creationTime |  expirationTime |  isSignUp |  isExpired |
+------+--------+---------------+-----------------+-----------+------------+

In the UserService should I just grab the information from these models, prepare the identity instance and return/use it?

OR

Am I better off having one User class (SocialUser class) with Identity trait and persist that?

You can think of this as an extension to https://stackoverflow.com/a/16389116/2343569. Basically, from a design point of view, is it better to persist PlatformUser or break PlatformUser into the classes (like User and AuthProviderForUser) and then persist those?

Which option is better? Any other suggestion?

Foi útil?

Solução

You could store everything in a single class and persist it to a single table row if you would always have only one external authentication option. In this case breaking that class down into 2 would not make much difference.

However, a single external authentication option is usually not the case. Even if you think at the moment that you only ever need to authenticate with Facebook you will usually later find the need to support other auth options. Thus it usually makes sense to design for multiple authentication options.

In your case you already know that there will be multiple authentication providers, so it makes sense to store them in a separate table and have a separate persistent entity class for that. You can still have authentication code in one place and easily extend functionality later by adding more auth providers.

Having said that if you would use MongoDB for example which lets you embed documents (rows) quite easily you could debate whether or not to store user and auth details as a single entity/row/document in DB. Even in this case both options would be of an equal preference in my opinion. But since you store data in relational DB - MySQL you should definitely normalize it to reasonable extent, and splitting it into 2 tables is the best option.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top