web-services - pagina - messenger facebook iniciar sesion
¿Diseñar/iniciar sesión o registrar recursos de forma RESTANTE? (7)
Creo que este es un enfoque RESTful para la autenticación. Para HttpPut
utiliza HttpPut
. Este método HTTP se puede usar para la creación cuando se proporciona la clave, y las llamadas repetidas son idempotentes. Para LogOff, especifica la misma ruta bajo el método HttpDelete
. Ningunos verbos utilizados. Adecuada pluralización de la colección. Los métodos HTTP respaldan el propósito.
[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }
[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }
Si lo desea, puede sustituir corriente por activa.
Estaba diseñando una aplicación web y luego me detuve a pensar cómo mi API debería diseñarse como un servicio web RESTful. Por ahora, la mayoría de mis URI son genéricos y pueden aplicarse a varias aplicaciones web:
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
Tengo la sensación de que estoy haciendo mucho mal aquí después de hurgar en SO y google.
Comenzando con /logout
, quizás debido a que realmente NO GET
nada, puede ser más apropiado enviar /logout
, destruir la sesión y luego GET
la redirección. ¿Y debería permanecer el término /logout
?
¿Qué pasa con /login
y /register
? Podría cambiar /register
/registration
pero eso no altera la forma en que mi servicio funciona fundamentalmente, si tiene problemas más profundos.
Ahora me doy cuenta de que nunca expongo un recurso /user
. Quizás eso podría ser utilizado de alguna manera. Por ejemplo, lleva al usuario myUser
:
foo.com/user/myUser
o
foo.com/user
El usuario final no requiere esa verbosidad adicional en el URI. Sin embargo, ¿cuál es más atractivo visualmente?
Me di cuenta de algunas otras preguntas aquí en SO sobre este negocio de REST, pero realmente agradecería alguna orientación sobre lo que he expuesto aquí si es posible.
¡Gracias!
ACTUALIZAR:
También me gustaría algunas opiniones sobre:
/user/1
vs
/user/myUserName
El uso y el diseño de API no se trata de URL visualmente atractivas , sino de URL que tienen sentido. Para el registro / inicio de sesión del usuario, los he usado en el pasado:
GET /user // Get multiple user info (limit ~10)
GET /user/1 // Get single user info
POST /user // Create user (registration)
PUT /user/1 // Edit user
POST /user/1/login // Login (could be GET, but I like sending more secure params by POST)
GET /user/1/logout // Logout
RESTful se puede utilizar como una guía para construir URL, y puede hacer que las sesiones y los recursos de los usuarios :
-
GET /session/new
obtiene la página web que tiene el formulario de inicio de sesión -
POST /session
autentica las credenciales contra la base de datos -
DELETE /session
destruye sesión y redirecciona a / -
GET /users/new
obtiene la página web que tiene el formulario de registro -
POST /users
registra la información ingresada en la base de datos como un nuevo / usuario / xxx -
GET /users/xxx
// obtiene y representa los datos del usuario actual en una vista de perfil -
POST /users/xxx
// actualiza nueva información sobre el usuario
Estos pueden ser plurales o singulares (no estoy seguro de cuál es el correcto). Por lo general, he utilizado /users
para una página de índice de usuario (como se esperaba) y /sessions
para ver quién está conectado (como se esperaba).
El uso del nombre en la URL en lugar de un número ( /users/43
vs. /users/joe
) suele estar motivado por el deseo de ser más amigable con los usuarios o los motores de búsqueda, y no por los requisitos técnicos. Cualquiera de las dos está bien, pero te recomendaría que seas consecuente.
Creo que si vas con el registro / inicio de sesión / cerrar sesión o sign(in|up|out)
, no funciona tan bien con la terminología tranquila.
Recomendaría utilizar una URL de cuenta de usuario similar a Twitter, donde la URL de la cuenta del usuario sería algo así como foo.com/myUserName
mismo modo que puede acceder a mi cuenta de Twitter con la URL https://twitter.com/joelbyler
No estoy de acuerdo con la desconexión que requiere un POST. Como parte de su API, si va a mantener una sesión, una identificación de sesión en forma de UUID podría ser algo que pueda usarse para realizar un seguimiento de un usuario y confirmar que la acción que se está llevando a cabo está autorizada. Entonces, incluso un GET puede pasar la identificación de la sesión al recurso.
En resumen, recomendaría que lo mantuviera simple, las URL deberían ser cortas e inolvidables.
Simplemente voy a hablar desde mi experiencia integrando varios servicios web REST para mis clientes, ya sea que se utilicen para aplicaciones móviles o para comunicación de servidor a servidor, así como para construir REST API para otros. Aquí hay algunas observaciones que he recopilado de la API REST de otras personas, así como aquellas que construimos nosotros mismos:
- Cuando decimos API, normalmente se refiere al conjunto de interfaz de programación y no es necesaria la capa de presentación. REST también está centrado en los datos y no en la presentación. Eso dice que la mayoría de los datos de retorno de REST aparecen en forma de JSON o XML y rara vez devuelven una capa de presentación específica. Este rasgo (de devolución de datos y no de la página web directa) le otorga a REST la capacidad de realizar entregas de múltiples canales. Lo que significa que el mismo servicio web se puede representar en HTML, iOS, Android o incluso como combinación de servidor a servidor.
- Es muy raro combinar HTML y REST como una URL. Por defecto, REST son pensamientos como servicios y no tienen capa de presentación. Es el trabajo para aquellos que consumen los servicios web para representar los datos de los servicios que llaman de acuerdo con lo que quieren. Hasta ese punto, su URL a continuación no concuerda con la mayoría del diseño basado en REST que he encontrado hasta ahora (ni los estándares, como los que provienen de Facebook o Twitter).
GET /register // gets the webpage that has the registration form
- Continuando con el punto anterior, también es poco común (y no me he encontrado) que el servicio REST haga una redirección, como las que se sugieren a continuación:
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
Como REST se diseñan como servicios, una función como el inicio de sesión y el cierre de sesión normalmente arrojan resultados de éxito / fracaso (normalmente en formato de datos JSON o XML) que luego el consumidor interpretaría. Tal interpretación podría incluir la redirección a la página web apropiada como usted mencionó
- En REST, la URL significa las acciones que se toman. Por esa razón, debemos eliminar tanta ambigüedad como sea posible. Si bien es legítimo en su caso tener tanto GET como POST que tengan la misma ruta (como / register) que realizan diferentes acciones, dicho diseño introduce ambigüedad en los servicios prestados y puede confundir al consumidor de sus servicios. Por ejemplo, las URL como la que presenta a continuación no son ideales para servicios basados en REST
GET /register // gets the webpage that has the registration form POST /register // records the entered information into database as a new /user/xxx
Esos son algunos puntos de lo que he tratado. Espero que pueda proporcionar algunas ideas para usted.
Ahora, en lo que respecta a la implementación de su REST, esta es la implementación típica que he encontrado:
GET /logout
Ejecute el cierre de sesión en el backend y devuelva JSON para indicar el éxito / error de la operación
POST /login
Enviar credenciales al backend. Retorno éxito / fracaso. Si tiene éxito, normalmente también devolverá el token de sesión y la información del perfil.
POST /register
Enviar registro al backend. Retorno éxito / fracaso. Si tiene éxito, normalmente se trata igual que el inicio de sesión exitoso o puede optar por hacer el registro como un servicio distinto
GET /user/xxx
Obtenga el perfil de usuario y devuelva el formato de datos JSON para el perfil del usuario
POST /user/xxx // renamed to POST /updateUser/xxx
Publicar información de perfil actualizada como formato JSON y actualizar la información en el back-end. Retorno éxito / falla a la persona que llama
Una cosa sobresale en particular como no REST-ful: el uso de una solicitud GET para cerrar la sesión.
(de http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_methods )
Algunos métodos (por ejemplo, HEAD, GET, OPTIONS y TRACE) se definen como seguros, lo que significa que están destinados solo a la recuperación de información y no deben cambiar el estado del servidor. En otras palabras, no deberían tener efectos secundarios, más allá de efectos relativamente inofensivos como el registro, el almacenamiento en caché, la publicación de anuncios publicitarios o el incremento de un contador web. [...]
[... H] andling [de solicitudes GET] por el servidor no está técnicamente limitado de ninguna manera. Por lo tanto, la programación descuidada o deliberada puede causar cambios no triviales en el servidor. Esto se desaconseja, ya que puede causar problemas para el almacenamiento en caché de la Web, los motores de búsqueda y otros agentes automatizados [...]
En cuanto a cerrar la sesión y redirigir, puede hacer que una publicación en su URI de cierre de sesión dé una respuesta 303 redireccionando a la página posterior al cierre de sesión.
http://en.wikipedia.org/wiki/Post/Redirect/Get
http://en.wikipedia.org/wiki/HTTP_303
Editar para abordar las preocupaciones de diseño de URL:
"¿Cómo diseño mis recursos?" es una pregunta importante para mí; "¿Cómo diseño mis URL?" es una consideración en dos áreas:
Las URL que los usuarios verán no deberían ser demasiado feas y significativas si es posible; si desea que se envíen cookies en solicitudes a algún recurso pero no a otros, querrá estructurar sus rutas y rutas de cookies.
Si JRandomUser
desea ver su propio perfil y desea que la URL sea más bonita que foo.com/user/JRandomUser
o foo.com/user/(JRandom''s numeric user id here)
, podría crear una URL separada solo para un usuario para ver su propia información:
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.
*/
Yo reclamaría la ignorancia mucho más fácilmente que la sabiduría sobre este tema, pero aquí hay algunas consideraciones de diseño de recursos:
- Consumidor: ¿qué recursos están destinados a ser vistos directamente en un navegador, cargados a través de XHR o accedidos por algún otro tipo de cliente?
- Acceso / identidad: ¿la respuesta depende de las cookies o referencias?
Las sesiones no son RESTful
Sí, lo sé. Se está haciendo, generalmente con OAuth, pero realmente las sesiones no son RESTful. No debe tener un recurso / iniciar / cerrar sesión principalmente porque no debería tener sesiones.
Si vas a hacerlo, hazlo RESTful. Los recursos son sustantivos y / login y / logout no son sustantivos. Me gustaría ir con / sesión. Esto hace que la creación y eliminación sea una acción más natural.
POST vs. GET para sesiones es fácil. Si está enviando usuario / contraseña como variables, usaría POST porque no deseo que se envíe la contraseña como parte del URI. Aparecerá en los registros y posiblemente se expondrá a través del cable. También corre el riesgo de que el software falle en las limitaciones de GET args.
Generalmente utilizo Basic Auth o no Auth con servicios REST.
Crear usuarios
Es un recurso, por lo que no debería necesitar / registrarse.
- POST / usuario: crea un usuario si el solicitante no puede especificar el id.
- PUT / user / xxx - Crea o actualiza un usuario suponiendo que conoces el id de antemano
- GET / user: enumera x ID de usuario
- GET / user / xxx - OBTIENE los detalles del usuario con id xxx
- DELETE / user / xxx - Eliminar el usuario con id xxx
Qué tipo de identificación usar es una pregunta difícil. Debe pensar en aplicar la unicidad, en la reutilización de los ID antiguos que fueron ELIMINADOS. Por ejemplo, no desea utilizar esos identificadores como claves externas en un back-end si los identificadores van a ser reciclados (si es posible). Sin embargo, puede realizar una búsqueda para la conversión de id. Externo / interno para mitigar los requisitos de back-end.