Creating user record / profile for first time sign in

倾然丶 夕夏残阳落幕 提交于 2019-12-24 11:28:38

问题


I use an authentication service Auth0 to allow users to log into my application. The application is a Q&A platform much like stackoverflow. I store a user profile on my server with information such as: 'about me', votes, preferences, etc.

When new user signs in i need to do 1 of 2 things:

  1. For an existing user - retrieve the user profile from my api server
  2. For a new user - create a new profile on the database

After the user signs in, Auth0(the authentication service) will send me some details(unique id, name and email) about the user but it does not indicate whether this is a new user(a sign up) or a existing user(a sign in).

This is not a complex problem but it would be good to understand best practice. I can think of 2 less than ideal ways to deal with this:

**Solution 1 - GET request **

  • Send a get request to api server passing the unique id
  • If a record is found return it
  • Else create new profile on db and return the new profile

This seems incorrect because the GET request should not be writing to the server.

**Solution 2 - One GET and a conditional POST request **

  • Send a get request to api server passing the unique id
  • The server checks the db and returns the profile or an error message
  • If the api server returns an error message send a post request to create a new profile
  • Else redirect to the home page

This seems inefficient because we need 2 requests to achieve a simple result.

Can anyone shed some light on what's best practice?


回答1:


There's an extra option. You can use a rule in Auth0 to send a POST to the /users/create endpoint in your API server when it's the first time the user is logging in, assuming both the user database in Auth0 and in your app are up-to-date.

It would look something like this:

[...]

var loginCount = context.stats.loginsCount;

if (loginCount == 1) {
  // send POST to your API and create the user
  // most likely you'll want to await for response before moving on with the login flow
}

[...]

If, on the other hand, you're referring to proper API design and how to implement a find-or-create endpoint that's RESTful, maybe this answer is useful.




回答2:


There seems to be a bit of disagreement on the best approach and some interesting subtleties as discussed in this post: REST Lazy Reference Create GET or POST?

Please read the entire post but I lean towards @Cormac Mulhall and @Blake Mitchell answers:

The client wants the current state of the resource from the server. It is not aware this might mean creating a resource and it does not care one jolt that this is the first time anyone has attempted to get this resource before, nor that the server has to create the resource on its end.

The following quote from The RESTful cookbook provided by @Blake Mitchell makes a subtle distinction which also supports Mulhall's view:

What are idempotent and/or safe methods? Safe methods are HTTP methods that do not modify resources. For instance, using GET or HEAD on a resource URL, should NEVER change the resource. However, this is not completely true. It means: it won't change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation.

Finally this key distinction is made in Section 9.1.1 of the HTTP specification:

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

Going back to the initial question, the above seems to support Solution 1 which is to create the profile on the server if it does not already exist.



来源:https://stackoverflow.com/questions/55033237/creating-user-record-profile-for-first-time-sign-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!