Autorización del acceso a las API REST con OAuth 2.0
Azure DevOps Services
Nota
La siguiente guía está pensada para Azure DevOps Services usuarios, ya que OAuth 2.0 no se admite en Azure DevOps Server. Las bibliotecas de cliente son una serie de paquetes creados específicamente para ampliar Azure DevOps Server funcionalidad. Para los usuarios locales, se recomienda usar bibliotecasde cliente, Windows autenticación o tokens de acceso personal (PAT) para autenticarse en nombre de un usuario.
Autentique a los usuarios de la aplicación web para el acceso a la API REST, de modo que la aplicación no siga solicitando nombres de usuario y contraseñas. Azure DevOps Services el protocolo OAuth 2.0 para autorizar a la aplicación para un usuario y generar un token de acceso. Use este token al llamar a las API REST desde la aplicación.
Cuando llame a Azure DevOps Services API para ese usuario, use el token de acceso de ese usuario. Los tokens de acceso expiran, por lo que debe actualizar el token de acceso si ha expirado.
Para obtener un ejemplo de C# del flujo general, vea vsts-auth-samples.
Registro de la aplicación
Vaya a https://app.vsaex.visualstudio.com/app/register para registrar la aplicación.
Asegúrese de seleccionar los ámbitos que necesita la aplicación y, a continuación, use los mismos ámbitos al autorizar la aplicación. Si registró la aplicación con las API de versión preliminar, vuelva a registrarla porque los ámbitos que usó ahora están en desuso.
Cuando Azure DevOps Services la página de aprobación de autorización al usuario, usa el nombre de la empresa, el nombre de la aplicación y las descripciones. También usa las direcciones URL del sitio web de la empresa, el sitio web de la aplicación y las declaraciones de términos de servicio y privacidad.
Cuando Azure DevOps Services solicita la autorización de un usuario y el usuario la concede, el explorador del usuario se redirige a la dirección URL de devolución de llamada de autorización con el código de autorización. La dirección URL de devolución de llamada debe ser una conexión segura (https) para transferir el código de vuelta a la aplicación. Debe coincidir exactamente con la dirección URL registrada en la aplicación. Si no es así, se muestra una página de error 400 en lugar de una página que pide al usuario que conceda autorización a la aplicación.
Al registrar la aplicación, se muestra la página de configuración de la aplicación.
Llame a la dirección URL de autorización y pase el identificador de la aplicación y los ámbitos autorizados cuando desee que un usuario autorice a la aplicación para acceder a su organización. Llame a la dirección URL del token de acceso cuando desee obtener un token de acceso para llamar a Azure DevOps Services API REST.
La configuración de cada aplicación que registre está disponible en el perfil https://app.vssps.visualstudio.com/profile/view .
Autorización de la aplicación
Si el usuario aún no ha autorizado a la aplicación para acceder a su organización, llame a la dirección URL de autorización.
https://app.vssps.visualstudio.com/oauth2/authorize
?client_id={app ID}
&response_type={Assertion}
&state={state}
&scope={scope}
&redirect_uri={callback URL}
| Parámetro | Tipo | Notas |
|---|---|---|
| client_id | GUID | Identificador asignado a la aplicación cuando se registró. |
| response_type | string | Assertion |
| state | string | Puede ser cualquier valor. Normalmente, un valor de cadena generado que correlaciona la devolución de llamada con su autorización asociada. Petición. |
| scope | string | Ámbitos registrados con la aplicación. Espacio separado. Consulte los ámbitos disponibles. |
| redirect_uri | Dirección URL | Dirección URL de devolución de llamada de la aplicación. Debe coincidir exactamente con la dirección URL registrada con la aplicación. |
Azure DevOps Services pide al usuario que autorice la aplicación. Controla la autenticación y, a continuación, le llama con un código de autorización, si el usuario aprueba la autorización.
Agregue un vínculo o botón al sitio que lleve al usuario al punto de conexión Azure DevOps Services autorización:
https://app.vssps.visualstudio.com/oauth2/authorize
?client_id=88e2dd5f-4e34-45c6-a75d-524eb2a0399e
&response_type=Assertion
&state=User1
&scope=vso.work%20vso.code_write
&redirect_uri=https://fabrikam.azurewebsites.net/myapp/oauth-callback
Azure DevOps Services solicita al usuario que autorice la aplicación.
Suponiendo que el usuario acepta, Azure DevOps Services redirige el explorador del usuario a la dirección URL de devolución de llamada, incluido un código de autorización de corta duración y el valor de estado proporcionado en la dirección URL de autorización:
https://fabrikam.azurewebsites.net/myapp/oauth-callback
?code={authorization code}
&state=User1
Obtener un token de acceso y actualización para el usuario
Ahora usa el código de autorización para solicitar un token de acceso (y un token de actualización) para el usuario. El servicio debe realizar una solicitud HTTP de servicio a servicio para Azure DevOps Services.
Dirección URL: autorización de la aplicación
POST https://app.vssps.visualstudio.com/oauth2/token
Encabezados de solicitud HTTP: autorizar aplicación
| Encabezado | Value |
|---|---|
| Content-Type | application/x-www-form-urlencoded |
| Content-Length | Longitud de cadena calculada del cuerpo de la solicitud (vea el ejemplo siguiente) |
Content-Type: application/x-www-form-urlencoded
Content-Length: 1322
Cuerpo de la solicitud HTTP: autorizar aplicación
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}
Reemplace los valores de marcador de posición en el cuerpo de la solicitud de ejemplo anterior:
- {0}: secreto de cliente codificado en dirección URL adquirido cuando se registró la aplicación
- {1}: el "código" codificado en la dirección URL proporcionado a través del
codeparámetro de consulta a la dirección URL de devolución de llamada - {2}: dirección URL de devolución de llamada registrada con la aplicación
Ejemplo de C# para formar el cuerpo de la solicitud: autorización de la aplicación
public string GenerateRequestPostData(string appSecret, string authCode, string callbackUrl)
{
return String.Format("client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion={1}&redirect_uri={2}",
HttpUtility.UrlEncode(appSecret),
HttpUtility.UrlEncode(authCode),
callbackUrl
);
}
Respuesta: autorización de la aplicación
{
"access_token": { access token for the user },
"token_type": { type of token },
"expires_in": { time in seconds that the token remains valid },
"refresh_token": { refresh token to use to acquire a new access token }
}
Importante
Conserve de forma segura la refresh_token para que la aplicación no tenga que pedir al usuario que vuelva a autorizar. Los tokens de acceso expiran relativamente rápidamente y no deben conservarse.
Uso del token de acceso
Para usar un token de acceso, inscluyéndolo como token de portador en el encabezado Authorization de la solicitud HTTP:
Authorization: Bearer {access_token}
Por ejemplo, la solicitud HTTP para obtener compilaciones recientes para un proyecto:
GET https://dev.azure.com/myaccount/myproject/_apis/build-release/builds?api-version=3.0
Authorization: Bearer {access_token}
Actualización de un token de acceso expirado
Si expira el token de acceso de un usuario, puede usar el token de actualización que adquirió en el flujo de autorización para obtener un nuevo token de acceso. Es como el proceso original para intercambiar el código de autorización para un token de acceso y actualización.
URL: token de actualización
POST https://app.vssps.visualstudio.com/oauth2/token
Encabezados de solicitud HTTP: token de actualización
| Encabezado | Value |
|---|---|
| Content-Type | application/x-www-form-urlencoded |
| Content-Length | Longitud de cadena calculada del cuerpo de la solicitud (vea el ejemplo siguiente) |
Content-Type: application/x-www-form-urlencoded
Content-Length: 1654
Cuerpo de la solicitud HTTP: token de actualización
client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={0}&grant_type=refresh_token&assertion={1}&redirect_uri={2}
Reemplace los valores de marcador de posición en el cuerpo de la solicitud de ejemplo anterior:
- {0}: secreto de cliente codificado en dirección URL adquirido cuando se registró la aplicación
- {1}: token de actualización con codificación URL para el usuario
- {2}: dirección URL de devolución de llamada registrada con la aplicación
Respuesta: token de actualización
{
"access_token": { access token for this user },
"token_type": { type of token },
"expires_in": { time in seconds that the token remains valid },
"refresh_token": { new refresh token to use when the token has timed out }
}
Importante
Se emite un nuevo token de actualización para el usuario. Conserve este nuevo token y úselo la próxima vez que necesite adquirir un nuevo token de acceso para el usuario.
Ámbitos
Importante
Los ámbitos solo permiten el acceso a las API REST y seleccionan puntos de conexión de Git. No se admite el acceso a la API SOAP.
| Categoría | Ámbito | Nombre | Descripción |
|---|---|---|---|
| Grupos de agentes | vso.agentpools |
Grupos de agentes (lectura) | Concede la capacidad de ver tareas, grupos, colas, agentes y trabajos actualmente en ejecución o completados recientemente para los agentes. |
vso.agentpools_manage |
Grupos de agentes (lectura, administración) | Concede la capacidad de administrar grupos, colas y agentes. | |
vso.environment_manage |
Entorno (lectura, administración) | Concede la capacidad de administrar grupos, colas, agentes y entornos. | |
| Analytics | vso.analytics |
Análisis (lectura) | Concede la capacidad de consultar datos de análisis. |
| Registro de auditoría | vso.auditlog |
Registro de auditoría (lectura) | Concede a los usuarios la capacidad de leer el registro de auditoría. |
| Compilar | vso.build |
Compilación (lectura) | Concede la capacidad de acceder a los artefactos de compilación, incluidos los resultados de compilación, las definiciones y las solicitudes, y la capacidad de recibir notificaciones sobre eventos de compilación a través de enlaces de servicio. |
vso.build_execute |
Compilación (lectura y ejecución) | Concede la capacidad de acceder a los artefactos de compilación, incluidos los resultados de compilación, las definiciones y las solicitudes, y la capacidad de poner en cola una compilación, actualizar las propiedades de compilación y la capacidad de recibir notificaciones sobre eventos de compilación a través de enlaces de servicio. | |
| Código | vso.code |
Código (leer) | Concede la capacidad de leer el código fuente y los metadatos sobre confirmaciones, conjuntos de cambios, ramas y otros artefactos de control de versiones. También concede la capacidad de buscar código y recibir notificaciones sobre eventos de control de versiones a través de enlaces de servicio. |
vso.code_write |
Código (lectura y escritura) | Concede la capacidad de leer, actualizar y eliminar código fuente, acceder a metadatos sobre confirmaciones, conjuntos de cambios, ramas y otros artefactos de control de versiones. También concede la capacidad de crear y administrar solicitudes de extracción y revisiones de código y recibir notificaciones sobre eventos de control de versiones a través de enlaces de servicio. | |
vso.code_manage |
Código (lectura, escritura y administración) | Concede la capacidad de leer, actualizar y eliminar código fuente, acceder a metadatos sobre confirmaciones, conjuntos de cambios, ramas y otros artefactos de control de versiones. También concede la capacidad de crear y administrar repositorios de código, crear y administrar solicitudes de extracción y revisiones de código, y recibir notificaciones sobre eventos de control de versiones a través de enlaces de servicio. | |
vso.code_full |
Código (completo) | Concede acceso total al código fuente, los metadatos sobre confirmaciones, conjuntos de cambios, ramas y otros artefactos de control de versiones. También concede la capacidad de crear y administrar repositorios de código, crear y administrar solicitudes de extracción y revisiones de código, y recibir notificaciones sobre eventos de control de versiones a través de enlaces de servicio. También incluye compatibilidad limitada con las API de OM de cliente. | |
vso.code_status |
Código (estado) | Concede la capacidad de leer y escribir el estado de confirmación y solicitud de extracción. | |
| Derechos | vso.entitlements |
Derechos (lectura) | Proporciona acceso de solo lectura al punto de conexión de derechos de licencia para obtener derechos de cuenta. |
vso.memberentitlementmanagement |
MemberEntitlement Management (lectura) | Concede la capacidad de leer a los usuarios, sus licencias, así como los proyectos y extensiones a los que pueden acceder. | |
vso.memberentitlementmanagement_write |
MemberEntitlement Management (escritura) | Concede la capacidad de administrar usuarios, sus licencias, así como proyectos y extensiones a los que pueden acceder. | |
| Extensiones | vso.extension |
Extensiones (lectura) | Concede la capacidad de leer las extensiones instaladas. |
vso.extension_manage |
Extensiones (lectura y administración) | Concede la capacidad de instalar, desinstalar y realizar otras acciones administrativas en las extensiones instaladas. | |
vso.extension.data |
Datos de extensión (lectura) | Concede la capacidad de leer datos (configuración y documentos) almacenados por las extensiones instaladas. | |
vso.extension.data_write |
Datos de extensión (lectura y escritura) | Concede la capacidad de leer y escribir datos (configuración y documentos) almacenados por las extensiones instaladas. | |
| Graph identidad | vso.graph |
Graph (lectura) | Concede la capacidad de leer información de pertenencia a grupos, grupos, grupos y usuarios. |
vso.graph_manage |
Graph (administrar) | Concede la capacidad de leer la información de pertenencia a usuarios, grupos, ámbitos y grupos, así como de agregar usuarios, grupos y administrar pertenencias a grupos. | |
vso.identity |
Identidad (leer) | Concede la capacidad de leer identidades y grupos. | |
vso.identity_manage |
Identidad (administrar) | Concede la capacidad de leer, escribir y administrar identidades y grupos. | |
| Prueba de carga | vso.loadtest |
Prueba de carga (lectura) | Concede la capacidad de leer las ejecuciones de pruebas de carga, los resultados de las pruebas y los artefactos de APM. |
vso.loadtest_write |
Prueba de carga (lectura y escritura) | Concede la capacidad de crear y actualizar ejecuciones de pruebas de carga y leer metadatos, incluidos los resultados de las pruebas y los artefactos de APM. | |
| Grupo de equipos | vso.machinegroup_manage |
Grupo de implementación (lectura, administración) | Proporciona la capacidad de administrar grupos de agentes y grupos de implementaciones. |
| Marketplace | vso.gallery |
Marketplace | Concede acceso de lectura a los publicadores y elementos públicos y privados. |
vso.gallery_acquire |
Marketplace (adquirir) | Concede acceso de lectura y la capacidad de adquirir elementos. | |
vso.gallery_publish |
Marketplace (publicar) | Concede acceso de lectura y la capacidad de cargar, actualizar y compartir elementos. | |
vso.gallery_manage |
Marketplace (administrar) | Concede acceso de lectura y la capacidad de publicar y administrar elementos y publicadores. | |
| Notificaciones | vso.notification |
Notificaciones (lectura) | Proporciona acceso de lectura a suscripciones y metadatos de eventos, incluidos los valores de campo filtrables. |
vso.notification_write |
Notificaciones (escritura) | Proporciona acceso de lectura y escritura a las suscripciones y acceso de lectura a los metadatos de eventos, incluidos los valores de campo filtrables. | |
vso.notification_manage |
Notificaciones (administrar) | Proporciona acceso de lectura, escritura y administración a las suscripciones y acceso de lectura a los metadatos de eventos, incluidos los valores de campo filtrables. | |
vso.notification_diagnostics |
Notificaciones (diagnóstico) | Proporciona acceso a los registros de diagnóstico relacionados con las notificaciones y proporciona la capacidad de habilitar diagnósticos para suscripciones individuales. | |
| Empaquetado | vso.packaging |
Empaquetado (lectura) | Concede la capacidad de leer fuentes y paquetes. |
vso.packaging_write |
Empaquetado (lectura y escritura) | Concede la capacidad de crear y leer fuentes y paquetes. | |
vso.packaging_manage |
Empaquetado (lectura, escritura y administración) | Concede la capacidad de crear, leer, actualizar y eliminar fuentes y paquetes. | |
| Project y equipo | vso.project |
Proyecto y equipo (leer) | Concede la capacidad de leer proyectos y equipos. |
vso.project_write |
Project y equipo (lectura y escritura) | Concede la capacidad de leer y actualizar proyectos y equipos. | |
vso.project_manage |
Project y equipo (lectura, escritura y administración) | Concede la capacidad de crear, leer, actualizar y eliminar proyectos y equipos. | |
| Versión | vso.release |
Versión (lectura) | Concede la capacidad de leer artefactos de versión, incluidas las versiones, las definiciones de versión y el entorno de versión. |
vso.release_execute |
Versión (lectura, escritura y ejecución) | Concede la capacidad de leer y actualizar artefactos de versión, incluidas las versiones, las definiciones de versión y el entorno de versión, y la capacidad de poner en cola una nueva versión. | |
vso.release_manage |
Versión (lectura, escritura, ejecución y administración) | Concede la capacidad de leer, actualizar y eliminar artefactos de versión, incluidas las versiones, las definiciones de versión y el entorno de versión, y la capacidad de poner en cola y aprobar una nueva versión. | |
| Seguridad | vso.security_manage |
Seguridad (administración) | Concede la capacidad de leer, escribir y administrar permisos de seguridad. |
| Conexiones de servicio | vso.serviceendpoint |
Puntos de conexión de servicio (lectura) | Concede la capacidad de leer puntos de conexión de servicio. |
vso.serviceendpoint_query |
Puntos de conexión de servicio (lectura y consulta) | Concede la capacidad de leer y consultar puntos de conexión de servicio. | |
vso.serviceendpoint_manage |
Puntos de conexión de servicio (lectura, consulta y administración) | Concede la capacidad de leer, consultar y administrar puntos de conexión de servicio. | |
| Configuración | vso.settings |
Configuración (lectura) | Concede la capacidad de leer la configuración. |
vso.settings_write |
Configuración (lectura y escritura) | Concede la capacidad de crear y leer la configuración. | |
| Symbols | vso.symbols |
Símbolos (lectura) | Concede la capacidad de leer símbolos. |
vso.symbols_write |
Símbolos (lectura y escritura) | Concede la capacidad de leer y escribir símbolos. | |
vso.symbols_manage |
Símbolos (lectura, escritura y administración) | Concede la capacidad de leer, escribir y administrar símbolos. | |
| Grupos de tareas | vso.taskgroups_read |
Grupos de tareas (lectura) | Concede la capacidad de leer grupos de tareas. |
vso.taskgroups_write |
Grupos de tareas (lectura, creación) | Concede la capacidad de leer y crear grupos de tareas. | |
vso.taskgroups_manage |
Grupos de tareas (lectura, creación y administración) | Concede la capacidad de leer, crear y administrar grupos de tareas. | |
| Panel del equipo | vso.dashboards |
Paneles de equipo (lectura) | Concede la capacidad de leer la información del panel del equipo. |
vso.dashboards_manage |
Paneles de equipo (administrar) | Concede la capacidad de administrar la información del panel del equipo. | |
| Administración de pruebas | vso.test |
Administración de pruebas (lectura) | Concede la capacidad de leer planes de prueba, casos, resultados y otros artefactos relacionados con la administración de pruebas. |
vso.test_write |
Administración de pruebas (lectura y escritura) | Concede la capacidad de leer, crear y actualizar planes de prueba, casos, resultados y otros artefactos relacionados con la administración de pruebas. | |
| Tokens | vso.tokens |
Tokens de autorización delegados | Concede a los usuarios la capacidad de administrar tokens de autorización delegados. |
vso.tokenadministration |
Administración de tokens | Concede a los administradores de la organización la capacidad de administrar (ver y revocar) los tokens existentes. | |
| Perfil de usuario | vso.profile |
Perfil de usuario (leer) | Concede la capacidad de leer el perfil, las cuentas, las colecciones, los proyectos, los equipos y otros artefactos organizativos de nivel superior. |
vso.profile_write |
Perfil de usuario (escritura) | Concede la capacidad de escribir en el perfil. | |
| Grupos de variables | vso.variablegroups_read |
Grupos de variables (lectura) | Concede la capacidad de leer grupos de variables. |
vso.variablegroups_write |
Grupos de variables (lectura, creación) | Concede la capacidad de leer y crear grupos de variables. | |
vso.variablegroups_manage |
Grupos de variables (lectura, creación y administración) | Concede la capacidad de leer, crear y administrar grupos de variables. | |
| Wiki | vso.wiki |
Wiki (lectura) | Concede la capacidad de leer wikis, páginas wiki y datos adjuntos de wiki. También concede la capacidad de buscar páginas wiki. |
vso.wiki_write |
Wiki (lectura y escritura) | Concede la capacidad de leer, crear y actualizar wikis, páginas wiki y datos adjuntos de wiki. | |
| Elementos de trabajo | vso.work |
Elementos de trabajo (leer) | Concede la capacidad de leer elementos de trabajo, consultas, paneles, rutas de acceso de área e iteraciones, y otros metadatos relacionados con el seguimiento de elementos de trabajo. También concede la capacidad de ejecutar consultas, buscar elementos de trabajo y recibir notificaciones sobre eventos de elementos de trabajo a través de enlaces de servicio. |
vso.work_write |
Elementos de trabajo (lectura y escritura) | Concede la capacidad de leer, crear y actualizar elementos de trabajo y consultas, actualizar metadatos de la placa, rutas de acceso de área de lectura e iteraciones otros metadatos relacionados con el seguimiento de elementos de trabajo, ejecutar consultas y recibir notificaciones sobre eventos de elementos de trabajo a través de enlaces de servicio. | |
vso.work_full |
Elementos de trabajo (completo) | Concede acceso total a elementos de trabajo, consultas, trabajos pendientes, planes y metadatos de seguimiento de elementos de trabajo. También proporciona la capacidad de recibir notificaciones sobre eventos de elementos de trabajo a través de enlaces de servicio. |
Registre la aplicación y use ámbitos para indicar qué permisos Azure DevOps Services requiere la aplicación. Cuando los usuarios autorizan a la aplicación a acceder a su organización, la autorizan para esos ámbitos. La solicitud de la autorización pasa los mismos ámbitos que registró.
Para obtener más información, vea Crear datos adjuntos o seguimiento de elementos de trabajo.
Ejemplos
Puede encontrar un ejemplo de C# que implementa OAuth para llamar a Azure DevOps Services API REST en nuestro ejemplo de OAuth GitHub C#.
Preguntas más frecuentes (P+F)
P: ¿Puedo usar OAuth con mi aplicación de teléfono móvil?
A. No. Azure DevOps Services solo admite el flujo de servidor web, por lo que no hay ninguna manera de implementar OAuth, ya que no se puede almacenar de forma segura el secreto de la aplicación.
P: ¿Qué errores o condiciones especiales necesito controlar en mi código?
A: Asegúrese de controlar las condiciones siguientes:
- Si el usuario deniega el acceso a la aplicación, no se devuelve ningún código de autorización. No use el código de autorización sin comprobar la denegación.
- Si el usuario revoca la autorización de la aplicación, el token de acceso ya no es válido. Cuando la aplicación usa el token para acceder a los datos, se devuelve un error 401. Vuelva a solicitar autorización.
P: Quiero depurar mi aplicación web localmente. ¿Puedo usar localhost para la dirección URL de devolución de llamada al registrar mi aplicación?
A. Sí. Azure DevOps Services ahora permite localhost en la dirección URL de devolución de llamada. Asegúrese de usar como el principio de la dirección URL de https://localhost devolución de llamada al registrar la aplicación.
P: Aparece un error HTTP 400 al intentar obtener un token de acceso. ¿Qué podría estar mal?
A: Compruebe que establece el tipo de contenido en application/x-www-form-urlencoded en el encabezado de solicitud.
P: ¿Puedo usar OAuth con los puntos de conexión SOAP y las API REST?
A. No. OAuth solo se admite en las API REST en este momento.
P: ¿Cómo puedo obtener detalles de datos adjuntos para mi elemento de trabajo mediante Azure DevOps API REST?
A. En primer lugar, obtenga los detalles del elemento de trabajo con la API REST Elementos de trabajo- Obtener elemento de trabajo:
GET https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}
Para obtener los detalles de los datos adjuntos, debe agregar el parámetro siguiente a la dirección URL:
$expand=all
Con los resultados, obtiene la propiedad de relaciones. Allí puede encontrar la dirección URL de los datos adjuntos y, dentro de la dirección URL, puede encontrar el identificador. Por ejemplo:
$url = https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/434?$expand=all&api-version=5.0
$workItem = Invoke-RestMethod -Uri $url -Method Get -ContentType application/json
$split = ($workitem.relations.url).Split('/')
$attachmentId = $split[$split.count - 1]
# Result: 1244nhsfs-ff3f-25gg-j64t-fahs23vfs