developer tip

/ 로그인 또는 / 등록 리소스를 RESTfully 설계 하시겠습니까?

optionbox 2020. 8. 11. 08:22
반응형

/ 로그인 또는 / 등록 리소스를 RESTfully 설계 하시겠습니까?


나는 웹 앱을 디자인하고 있었고 내 API가 RESTful 웹 서비스로 어떻게 디자인되어야하는지 생각하기 위해 멈추었습니다. 현재 대부분의 URI는 일반적이며 다양한 웹 앱에 적용될 수 있습니다.

GET  /logout   // destroys session and redirects to /
GET  /login    // gets the webpage that has the login form
POST /login    // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET  /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET  /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user

나는 SO와 Google을 둘러 본 후 여기에서 많이 잘못하고 있다고 느낍니다.

로 시작 /logout하면 아마도 내가 GET아무것도 하지 않기 때문에 , 세션을 파괴 한 다음 리디렉션을 POST요청하는 것이 더 적절할 수 있습니다 . 그리고 그 기간이 유지 되어야 합니까?/logoutGET/logout

무엇에 대한 /login/register. 로 변경할 /register수는 /registration있지만 더 깊은 문제가있는 경우 내 서비스가 근본적으로 작동하는 방식을 변경하지는 않습니다.

이제는 /user리소스를 노출하지 않습니다 . 아마도 그것은 어떻게 든 활용할 수있을 것입니다. 예를 들어 다음과 같은 사용자를 가져옵니다 myUser.

foo.com/user/myUser

또는

foo.com/user

최종 사용자는 URI에 추가 상세 정보가 필요하지 않습니다. 그러나 어느 것이 시각적으로 더 매력적입니까?

이 REST 비즈니스에 대해 여기에서 다른 질문을 발견했지만 가능하면 여기에 배치 한 지침에 대해 감사하겠습니다.

감사!

최신 정보:

또한 다음에 대한 몇 가지 의견을 원합니다.

/user/1

vs

/user/myUserName

특히 REST-ful이 아닌 것으로 눈에 띄는 한 가지는 로그 아웃을 위해 GET 요청을 사용하는 것입니다.

( http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods에서 )

일부 메소드 (예 : HEAD, GET, OPTIONS 및 TRACE)는 안전한 것으로 정의됩니다. 즉, 정보 검색 용으로 만 사용되며 서버 상태를 변경해서는 안됩니다. 즉, 로깅, 캐싱, 배너 광고 제공 또는 웹 카운터 증가와 같은 상대적으로 무해한 효과 이상의 부작용이 없어야합니다. [...]

[...] 서버에 의한 [GET 요청 처리] 처리는 기술적으로 어떤 식 으로든 제한되지 않습니다. 따라서 부주의하거나 의도적 인 프로그래밍으로 인해 서버에 사소하지 않은 변경이 발생할 수 있습니다. 이것은 웹 캐싱, 검색 엔진 및 기타 자동화 에이전트에 문제를 일으킬 수 있기 때문에 권장되지 않습니다. [...]

로그 아웃 및 리디렉션의 경우 로그 아웃 URI에 대한 게시물이 로그 아웃 후 페이지로 리디렉션되는 303 응답을 제공하도록 할 수 있습니다.

http://en.wikipedia.org/wiki/Post/Redirect/Get

http://en.wikipedia.org/wiki/HTTP_303

URL 디자인 문제를 해결하기 위해 편집 :

"자원을 어떻게 디자인합니까?" 나에게 중요한 질문입니다. "URL은 어떻게 디자인합니까?" 두 가지 영역에서 고려할 사항입니다.

사용자에게 표시되는 URL은 가능하면 너무 추하고 의미가 없어야합니다. 일부 리소스에 대한 요청에서 쿠키를 전송하고 다른 리소스에는 전송하지 않으려면 경로와 쿠키 경로를 구조화해야합니다.

경우 JRandomUser욕구가 자신의 프로필을보고하고 URL보다 예뻐 할 foo.com/user/JRandomUser또는 foo.com/user/(JRandom's numeric user id here), 당신은 단지 자신의 정보를보고 사용자에 대한 별도의 URL을 만들 수 있습니다 :

GET foo.com/profile /*examines cookies to figure out who 
                     * is logged in (SomeUser) and then 
                     * displays the same response as a
                     * GET to foo.com/users/SomeUser.
                     */

나는이 주제에 대해 지혜보다 훨씬 더 쉽게 무지를 주장 할 것이지만, 여기에 몇 가지 리소스 설계 고려 사항이 있습니다.

  1. 소비자 : 브라우저에서 직접 보거나 XHR을 통해로드하거나 다른 종류의 클라이언트에서 액세스 할 수있는 리소스는 무엇입니까?
  2. 액세스 / 신원 : 응답이 쿠키 또는 리퍼러에 따라 달라 집니까?

RESTful은 URL 구성을위한 지침으로 사용할 수 있으며 세션사용자 리소스를 만들 있습니다.

  • GET /session/new 로그인 양식이있는 웹 페이지를 가져옵니다.
  • POST /session 데이터베이스에 대해 자격 증명을 인증합니다.
  • DELETE /session 세션을 파괴하고 /로 리디렉션
  • GET /users/new 등록 양식이있는 웹 페이지를 가져옵니다.
  • POST /users 입력 된 정보를 새로운 / user / xxx로 데이터베이스에 기록합니다.
  • GET /users/xxx // 프로필보기에서 현재 사용자 데이터를 가져오고 렌더링합니다.
  • POST /users/xxx // 사용자에 대한 새로운 정보를 업데이트합니다.

These can be plural or singular (I'm not sure which one is correct). I've usually used /users for a user index page (as expected), and /sessions to see who is logged in (as expected).

Using the name in the URL instead of a number (/users/43 vs. /users/joe) is usually driven by the desire to be more friendly to the users or search engines, not any technical requirements. Either is fine, but I'd recommend you are consistent.

I think if you go with the register/login/logout or sign(in|up|out), it doesn't work as well with the restful terminology.


Sessions aren't RESTful

  • Yes, I know. It's being done, usually with OAuth, but really sessions aren't RESTful. You shouldn't have a /login /logout resource primarily because you shouldn't have sessions.

  • If your going to do it, make it RESTful. Resources are nouns and /login and /logout aren't nouns. I would go with /session. This make creation and deletion a more natural action.

  • POST vs. GET for sessions is easy. If you are sending user/password as variables, I would use POST because I don't want to have the password sent as part of the URI. It will show up in logs and possibly be exposed over the wire. You also run the risk of having software fail on GET args limitations.

  • I generally use Basic Auth or no Auth with REST services.

Creating users

  • It's one resource, so you shouldn't need /register.

    • POST /user - Creates a user if the requestor cannot specify the id
    • PUT /user/xxx - Create or update a user assuming you know the id beforehand
    • GET /user - lists x user ids
    • GET /user/xxx - GETs the details of the user with id xxx
    • DELETE /user/xxx - Delete the user with id xxx
  • Which kind of ID to use is a hard question. You have to think about enforcing uniqueness, about reuse of old ids that were DELETEd. For example, you do not want to use those ids as foreign keys on a backend if ids are going to be recycled (if at all possible). You can have a lookup though for external/internal id conversion in order to mitigate backend requirements.


I am going to simply speak from my experience integrating various REST Web Services for my clients, whether it is used for mobile apps or for server to server communication as well as building REST API for others. Here are few observations that I have gathered from other people's REST API as well as those that we built ourselves:

  • When we say API, it normally refers to set of programming interface and not necessary the presentation layer. REST is also data centric and not presentation driven. That said most REST return data in the form of JSON or XML and rarely returning a specific presentation layer. This trait (of returning data and not the direct webpage) given REST ability to do multi-channels delivery. Meaning that the same webservice can be rendered in HTML, iOS, Android or even used as server to server combination.
  • It's very rare to combine both HTML and REST as a URL. By default REST are thoughts as services and not having presentation layer. It is the job for those who consume the webservices to render the data from the services that they call according to what they want. To that point your URL below does not conform with most REST based design that I've encountered thus far (nor the standards such as those who are coming from Facebook or Twitter)
GET  /register // gets the webpage that has the registration form
  • Continuing from previous point, it is also uncommon (and I have not encountered) for REST based service to do redirection such as the ones suggested below:
GET  /logout   // destroys session and redirects to /
POST /login    // authenticates credentials against database and either redirects home with a new session or redirects back to /login
 

As REST are designed as services, function such as login and logout are normally returning success/failure result (normally in JSON or XML data format) which then the consumer would interpret. Such interpretation could include the redirection to appropriate webpage as you mentioned

  • In REST, the URL signify the actions that is taken. For that reason, we should remove as much ambiguity as possible. While it is legitimate in your case to have both GET and POST that has the same path (such as /register) that perform different action, such design introduce ambiguity in services provided and may confuse the consumer of your services. For example, the URLs such as the one that you introduce below are not ideal for REST based services
GET  /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx

Those are some points from what I have dealt with. I hope it could provide some insights for you.

Now as far for implementation of your REST, these are the typical implementation that I have encountered:

  • GET  /logout  
    

    Execute logout in the backend and return JSON for denoting the success/failure of the operation

  • POST /login
    

    Submit credentials to the backend. Return success/failure. If successful, normally it will also return the session token as well as the profile information.

  • POST /register
    

    Submit registration to the backend. Return success/failure. If successful, normally treated the same as successful login or you could choose to make registration as a distinct service

  • GET  /user/xxx
    

    Get user profile and return JSON data format for the user's profile

  • POST /user/xxx 
    // renamed to 
    POST /updateUser/xxx
    

    Post updated profile information as JSON format and update the information in the backend. Return success/failure to the caller


I believe this is a RESTful approach to authentication. For LogIn you use HttpPut. This HTTP method can be used for creation when the key is provided, and repeated calls are idempotent. For LogOff, you specify the same path under the HttpDelete method. No verbs utilized. Proper collection pluralization. The HTTP methods support the purpose.

[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }

[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }

If desired you could substitute current for active.


I would recommend using a user account URL similar to twitter where the user's account URL would be something like foo.com/myUserName just like you can get to my twitter account with the URL https://twitter.com/joelbyler

I disagree about logout requiring a POST. As part of your API, if you are going to maintain a session, then a session id in the form of a UUID might be something that can be used to keep track of a user and confirm that the action being taken is authorized. Then even a GET can pass along the session id to the resource.

In short I would recommend that you keep it simple, URLs should be short an memorable.

참고URL : https://stackoverflow.com/questions/7140074/restfully-design-login-or-register-resources

반응형