Está en la página 1de 20

OAuth 2.

SERVIDOR DE AUTORIZACIÓN OAUTH 2.0

Contenido

Introducción 2
Propósito 2

Especificaciones técnicas 2
Pre - requisitos 2
Ejecución del programa 3
Variables de entorno 4
Desplegar Contenedor 6
Esquemas en la base de datos 6
Cargar datos en mongodb 8
Obtención del token 9
Obtención del token utilizando el formato base 64 9
Obtención del token utilizando el Body 10
Scopes 11
Respuesta de la solicitud 11

Transferencia de conocimiento 13
Tecnologías utilizadas 13
Funciones utilizadas 13
Servicios MongoDB 15
mongoUser 15
mongoClient 16
mongoToken 16
Modelos y Esquemas 16
Lógica principal 17
Respuestas de error y causas 18

Glosario 19

Referencias 19
OAuth 2.0

1. Introducción
El presente documento describe el sistema de autorización Oauth 2.0 para los
mecanismos de interconexión para los Sistemas 2 (S2) y 3 (S3) con la Plataforma
Digital Nacional (PDN) en un ambiente de pruebas. Esta información es
proporcionada a los equipos técnicos de las Secretarías Ejecutivas de los Sistemas
Locales Anticorrupción (SESLAs) y la Secretaría Ejecutiva del Sistema Nacional
Anticorrupción (SESNA) para la implementación de estos mecanismos, con datos
sintéticos, en tres estados pilotos (Chihuahua, Jalisco y Oaxaca).

Cada parte del proyecto cuenta con su respectiva documentación, el orden de la


misma para ir de principio a fin en la reproducción local del proyecto es:

1. Instalación: el cual muestra los pasos para la preparación del ambiente local,
contempla lo relacionado a Docker, Docker Compose y Mongo. Ref.[2].

2. Generador: documentación del generador de datos sintéticos para los dos


sistemas, Ref.[3].

3. OAuth2.0: documentación para la implementación del protocolo Oauth 2.0.


Este es el presente documento.

Adicionalmente, se cuenta con un Anexo que incluye una serie de guías sobre las
diversas tecnologías utilizadas:

● Anexo, Ref.[4].

1.1. Propósito

El propósito de este documento es proporcionar toda la información técnica


relevante con respecto a la implementación del mecanismo de autorización Oauth
2.0 utilizado en esta solución para el cliente.

2. Especificaciones técnicas
2.1. Pre - requisitos
Versión estable SLP (soporte de largo-plazo) de NodeJs y NPM previamente
instalados, si no se cuenta con ellos puede descargarlos del siguiente enlace
https://nodejs.org/en/download/
OAuth 2.0

Ambiente con la base de datos MongoDB instalado y configurado. Se asume que el


usuario conoce ya las credenciales asignadas a la base de datos, esta información
es indispensable. Para más información, vea el reporte de instalación, Ref.[2].

Se recomienda haber leído este documento en su totalidad antes de replicar el


servidor de autorización Oauth 2.0 de manera local.

2.2. Ejecución del programa

● El servicio del servidor de autorización Oauth 2.0 deberá descargarlo del


repositorio de Github de la PDN del siguiente link, siguiendo las instrucciones
que ahí se especifican.
https://github.com/PDNMX/piloto_oauth2.0

● Para clonar el repositorio desde el CLI (Interfaz de línea de comandos) de su


computador utilice el siguiente comando:

$ git clone https://github.com/PDNMX/piloto_oauth2.0.git

● Se le solicitará su usuario y contraseña de Github para acceder.

● Agregar el servicio oauth20 al archivo docker-compose.yml que se


encuentra en el directorio <home directory>/sistema_pdn/mongodb
de la siguiente forma:
version: '3.1'
services:
mongodb:
image: mongo
container_name: mongodb
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: ${DB_ROOT_USER}
MONGO_INITDB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- ./mongo-volume:/data/db
OAuth 2.0

- ./mongod.conf:/etc/mongod.conf
- ./log/:/var/log/mongodb/
env_file:
- .env
command: ["-f", "/etc/mongod.conf"]
oauth20:
restart: always
container_name: oauth20
build:
context: ../piloto_oauth2.0/
dockerfile: Dockerfile
ports:
- 9003:9003
links:
- mongodb
depends_on:
- mongodb
Nota: La identación es importante.

La variable context especifica la ubicación relativa ../piloto_oauth2.0/


donde fue descargada la aplicación, y además, contiene el archivo Dockerfile
incluido en la descarga de github.

La variable ports incluye el mapeo entre el puerto del host y el puerto interno del
contenedor 9003:9003.

2.3. Variables de entorno

El archivo donde se contemplan las variables de entorno estará localizado en la


siguiente ruta:
<home directory>/sistema_pdn/piloto_oauth2.0/config/config.env

Este archivo desde el repositorio viene vacío. A continuación, se muestra un ejemplo


del contenido que debe tener.

//Expiration token in seconds


EXT = 600
OAuth 2.0

//Expiration refresh token in seconds


RTEXT = 900

// SEED
SEED = YTBGD9YjAUhkjQk9ZXcb

//MONGO CONFIG

USERMONGO = oauthUsr
PASSWORDMONGO= Xy37v7TNhuDrB
HOSTMONGO = mongodb:27017
DATABASE= oauth20
PORTSERVER=9003
Nota: Las diagonales // al inicio de línea indican que es un comentario.

USERMONGO: Contiene el nombre del usuario oauthUsr para acceder a la base


de datos oauth20. Este usuario debe contar con los privilegios correspondientes y
fue creado durante la instalación de MongoDB, Ref.[2].

PASSWORDMONGO: Contiene el password Xy37v7TNhuDrB del usuario


oauthUsr para acceder a la base de datos oauth20.

HOSTMONGO: Contiene la dirección IP mongodb y el puerto 27017 donde se


encuentra alojada la base de datos. Se utiliza el link mongodb que se encuentra
declarado en el archivo docker-compose.yml en lugar de la dirección IP. En
este caso, tiene el valor de mongodb:27017.

DATABASE: Contiene el nombre de la base de datos oauth20.

PORTSERVER: Contiene el puerto 9003 en el que se ejecuta la aplicación.

Las variables de entorno que hacen referencia a nuestros tokens

EXT: Contiene el número de segundos 600 para la expiración del token.

RTEXT: Contiene el número de segundos 900 para la expiración del refresh token.
Este número debe ser mayor al tiempo de expiración del token.

SEED: Contiene la semilla YTBGD9YjAUhkjQk9ZXcb para la codificación del


JSON Web Token (JWT)

Cabe mencionar que el refresh token es un String aleatorio no un JWT, ya que el


refresh token se valida en el servidor de autorización. Por lo tanto, se puede obtener
OAuth 2.0

haciendo una petición a la base de datos y verificando los parámetros para generar
un nuevo token.

2.4. Desplegar Contenedor


● Una vez hecho lo anterior, ejecutar el docker compose desde el directorio
<home directory>/sistema_pdn/mongodb que contiene el archivo
docker-compose.yml de la siguiente forma:

$ docker-compose up -d

Nota: En caso que MongoDB ya esté corriendo en un contenedor, sólo


construirá la nueva imagen y se creará el nuevo contenedor oauth20.

● Verificar que
todos los contenedores dentro del archivo docker-
compose.yml estén corriendo con el siguiente comando:

$ docker-compose ps

Name Command State


Ports
------------------------------------------------------------------
-----------------
mongodb docker-entrypoint.sh -f /e ... Up
0.0.0.0:27017->27017/tcp
oauth20 docker-entrypoint.sh yarn ... Up
0.0.0.0:9003->9003/tcp
Nota: El resultado puede variar de la imagen mostrada, verifique que los
servicios definidos estén presentes en el resultado esperado.

2.5. Esquemas en la base de datos


Dentro de MongoDB, se tiene la base de datos oauth20 para las siguientes
colecciones que conciernen a la implementación Oauth 2.0, y que ya fueron creadas
durante la instalación de MongoDB, Ref.[2].

Usuarios
Nombre de la colección: users

Nombre del Tipo Valor posible Descripción


OAuth 2.0

campo

username String ‘ecamargo’ Nombre del usuario o


identificador

password String ‘123456’ Contraseña del usuario

[‘readWrite’ , Privilegios a los cuales


scope Array String
‘read’] se asocia este usuario

Clientes
Nombre de la colección: clients

Nombre del
Tipo Valor posible Descripción
campo

clientId String ‘txm.global’ Identificador del cliente

clientSecret String ‘pass’ Contraseña del cliente

Array Privilegios asociados con


grants [‘admin’]
String el cliente
Nota: En caso de que el valor clientSecret no se agregue al documento,
porque no existe en el ambiente, la solicitud POST no deberá contener dicho
parámetro o se puede colocar en el documento con un valor vacío, es decir, dos
comillas simples ‘’.

Tokens
Nombre de la colección: tokens

Nombre del
Tipo Valor posible Descripción
campo

access_token String 'eyJhbGciOiJIUzI1NiIsInR5cC Token en formato JWT el


I6IkpXVCJ9.eyJ1c2VybmFtZSI6 cual permite la validación
ImVjYW1hcmdvIiwianRpIjoiR1V
oQ1dNR0siLCJzY29wZSI6IndyaX
de identidad en el recurso
RlICIsImlhdCI6MTU5NTMwNDAwM protegido
OAuth 2.0

iwiZXhwIjoxNTk1MzA0MDYyfQ.n
5JLQo0fl7l0LbJ_anPfsA3O2r-
EMlGmvK0fJ-LP2Zg'

Tiempo de expiración del


expires_in Number 300 access_token en
segundos

'OztWyf5YGjPJxrkkx4feeRGT3e
up21yRMZgfMuNLrwBKvsIcKT3u6
PvyjGlfc951nLhr0tNOZT4UezG9
71FXUNBaUNDaWNO6h8Uzno62wJA Token (random string) el
refresh_token String
5K3iRF9smW4IdgmXMpkr4fB0C5K cual se utiliza para generar
fQmsjNZL02bTzrQBmJ4BEOTmRjs un nuevo token (flujo
eAkr0A3JQU3vFtIyyXHQWxVaW03 refresh token)
tNDgu001feEgQ15XilnmWq9zubn
gnnLLoZrN6bah3UhGxSwFgydgzR
9W19CpxDdryrsE'

refresh_token Tiempo de expiración del


Number 600
_expires_in refresh token en segundos

refresh_token unix timestamp de la


_expires_in_d Number 1595275826 expiracion del refresh
ate token

{clientId: Se almacena solo el id del


client Object
'pdn.resource.1'} cliente

user Object {username: 'ecamargo'} Se almacena el username

2.6. Cargar datos en mongodb


Para efecto práctico, se tienen que cargar los siguientes documentos en la base de
datos oauth20 por medio de mongo CLI.

1.- Entrar a la base de datos MongoDB con el siguiente comando:


$ mongo -u root -p --host <IP_HOST>
Nota: El parámetro <IP_HOST> se sustituye por la IP del servidor de MongoDB.

2.- Seleccionar la base de datos oauth20 ya dentro del prompt de mongo


> use oauth20
OAuth 2.0

3.- Insertar los documentos con el siguiente comando:


db.users.insert([
{
username: 'ecamargo',
password: '123456',
scope: ['read','readWrite']
}
])

db.clients.insert([{
clientId: 'txm.global',
clientSecret: 'pass',
grants: []
}
])

db.tokens.insert([{
Access_token:'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1
c2VybmFtZSI6ImVjYW1hcmdvIiwianRpIjoiR1VoQ1dNR0siLCJzY29
wZSI6IndyaXRlICIsImlhdCI6MTU5NTMwNDAwMiwiZXhwIjoxNTk1Mz
A0MDYyfQ.n5JLQo0fl7l0LbJ_anPfsA3O2r-EMlGmvK0fJ-LP2Zg',
expires_in: 300,
refresh_token:'OztWyf5YGjPJxrkkx4feeRGT3eup21yRMZgfMuNL
rwBKvsIcKT3u6PvyjGlfc951nLhr0tNOZT4UezG971FXUNBaUNDaWNO
6h8Uzno62wJA5K3iRF9smW4IdgmXMpkr4fB0C5KfQmsjNZL02bTzrQB
mJ4BEOTmRjseAkr0A3JQU3vFtIyyXHQWxVaW03tNDgu001feEgQ15Xi
lnmWq9zubngnnLLoZrN6bah3UhGxSwFgydgzR9W19CpxDdryrsE',
Refresh_token_expires_in: 600
Refresh_token_expires_in_date: 1595275826
client: {clientId: 'pdn.resource.1'},
user: {username: 'ecamargo'}
}
])
Nota: Los valores utilizados son para ejemplificar y servir de contexto para los
comandos en este documento.
OAuth 2.0

2.7. Obtención del token


2.7.1. Obtención del token utilizando el formato base 64
Para poder generar un nuevo token se requiere enviar una solicitud de tipo POST a
la ruta http://<IP_HOST>:9003/oauth/token. La variable <IP_HOST>
es la dirección IP donde está instalado el Sistema de la PDN.

Los parámetros se describen en el documento “Guía de referencia protocolo de


autorización” Ref.[1]. Los parámetros client_id y client_secret se pueden
enviar en el encabezado de la petición, y codificados en formato base 64. A
continuación, se mencionan los pasos para la obtención del token utilizando el
formato base 64:

1. Generar el formato base 64 utilizando los valores de client_id y


client_secret en los campos username y password del siguiente
enlace https://www.blitter.se/utils/basic-authentication-header-generator/

2. Obtener el token utilizando el formato base 64 generado en el paso anterior, por


ejemplo, dHhtLmdsb2JhbDpwYXNz, y ejecutando el siguiente comando
desde el CLI del sistema operativo de nuestro ordenador:

curl --location --request POST '<IP_HOST>:9003/oauth/token' \


--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic dHhtLmdsb2JhbDpwYXNz' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=ecamargo' \
--data-urlencode 'password=123456' \
--data-urlencode 'scope=read readWrite'
Nota: Se antepone la palabra Basic al formato base 64 generado Basic
dHhtLmdsb2JhbDpob2xh

2.7.2. Obtención del token utilizando el Body

Para poder generar un nuevo token se requiere enviar una solicitud de tipo POST a
la ruta http://<IP_HOST>:9003/oauth/token. La variable <IP_HOST>
es la dirección IP donde está instalado el Sistema de la PDN.
OAuth 2.0

La solicitud POST deberá incluir el parámetro cliente_id y opcionalmente el


parámetro client_secret dentro del body, sin la necesidad de la codificación en
formato base 64.

Como el parámetro client_secret es opcional, puede no ir dentro del


documento de la base de datos oauth20, o puede contener un valor vacío como
se muestra a continuación:
{
clientId: 'txm.global',
grants: []
}

{
clientId: 'txm.global',
clientSecret: "",
grants: []
}

Para obtener el token, se debe ejecutar el siguiente comando desde el CLI del
sistema operativo de nuestro ordenador
curl --location --request POST '<IP_HOST>:9003/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=txm.global' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=ecamargo' \
--data-urlencode 'password=123456' \
--data-urlencode 'scope=read' \
--data-urlencode 'client_secret=pass'

El Content-Type tiene que ser application/x-www-form-urlencoded


para poder enviar los parámetros y obtener la respuesta esperada.

En caso que el parámetro client_secret contenga un valor vacío, al momento


de generar la solicitud por el comando curl, se puede omitir o expresar como
sigue:

--data-urlencode 'client_secret='
OAuth 2.0

2.8. Scopes
Los scopes son privilegios que se relacionan directamente al usuario para restringir
el nivel de acceso a los recursos protegidos (API).

Cuando se envía una solicitud POST, se pueden enviar los scopes solicitados por
medio del parámetro scope, estos se validan en el servidor de autorización y se
agregan a la respuesta solamente en caso de estar asociados al usuario. En caso
de enviar en la petición un scope inválido para el usuario u omitir el scope para un
usuario que tiene scopes asociados, se retornará un mensaje de error.

Debido a que los scopes son opcionales, o sea, no están definidos; esto queda fuera
del alcance de la implementación Oauth 2.0. Se recomienda generar una colección
con ellos y generar un método de asociación hacia los usuarios.

2.9. Respuesta de la solicitud

{
"access_token":
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImVjYW1
hcmdvIiwianRpIjoiYjdjOFBEZkYiLCJzY29wZSI6InJlYWQgIiwiaWF0Ijox
NTk2MDU3ODI2LCJleHAiOjE1OTYwNTgxMjZ9.Zoe3oJwjsuM_0r2Z72fyZnaW
qO0yNLZ06jm3yReDzqE",
"token_type": "bearer",
"expires_in": 300,
"refresh_token":
"D2MeNrnDRnMBsLdV6LQkoDow7Y5Mt8eLgaM76FR3BNVbz6TdtXWXhvB6wLaR
R5jVaj2oCkNLge4ODw1TYSnop7dHJ4zRGgK0iE6CrlcXsrN97XVkYg8Kr75bW
KSBfAm3q4CoRPr31XB3XyV1agFTSdAbYQ6XutVxEsGytZg7ljDBeO0bKicVkS
F7qMTlFWilHtuG7mKCcRJd1y5dROhXI15TvemNlB5eD6LVyyyE3qmKf1Vx9nG
8MYZb4tSV8Ky5",
"refresh_token_expires_in": 600,
"scope": "read"
}
Nota: El resultado puede variar de la imagen mostrada, verifique que los parámetros
definidos estén presentes en la respuesta esperada.

Los parámetros se describen en el documento “Guía de referencia protocolo de


autorización”, Ref. [1], a continuación, se describen algunas consideraciones.
OAuth 2.0

El parámetro access_token es un JWT. Los JWT se generan con base en una


semilla que es una cadena de texto la cual se usa para codificar el JWT, y con esa
semilla es posible validarlo en el servidor de recursos protegidos, es decir, en el API.
De esta manera, evitamos el uso de la base de datos para conceder el acceso a los
recursos. Para mayor información sobre JWT, consulte el enlace
https://openwebinars.net/blog/que-es-json-web-token-y-como-funciona/

El JWT generado almacena los siguientes parámetros en el payload, los cuales


sirven para verificar si el token ha expirado (iat, exp), si el token tiene el privilegio
para usar el recurso (scope) o si necesitamos ver quien genera la operación
(username):
iat : tiempo de creación del token
exp: tiempo de expiración del token
scope: privilegios solicitados del usuario
username: nombre del usuario
jti: hace único al JWT (para evitar duplicados )

3. Transferencia de conocimiento
3.1. Tecnologías utilizadas

● NodeJS v12.18.2
● MongoDB 4.2.8

Se requiere que los documentos de clientes y usuarios estén previamente


generados, ver la sección Cargar datos en mongodb. Se puede acceder a la base
de datos y generar el documento, la estructura se encuentra disponible en la
sección Esquemas en la base de datos.

El archivo AuthorizationServer.js contiene la lógica del servidor de


autorización Oauth 2.0. Se describen sus funcionalidades y se desglosa cada punto
en las siguientes secciones.

Para poder acceder a la base de datos, se tiene el siguiente fragmento de código:


//connection mongo db
const db =
OAuth 2.0

mongoose.connect('mongodb://'+process.env.USERMONGO+':'+process.env
.PASSWORDMONGO+'@'+process.env.HOSTMONGO+'/'+process.env.DATABASE,
{ useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('Connect to MongoDB..'))
.catch(err => console.error('Could not connect to MongoDB..',
err))

3.2. Funciones utilizadas


La función createToken genera el token que se ingresará a la base de datos.
Como parámetros de entrada, tenemos el clientId , username y los
scopes.

function createToken(clientId,username, scope){


let expiresin = Number(process.env.EXT); //se obtienen los segundos
de vida del token

let access_token = jwt.sign({


username: username,
jti: randomstring.generate(8),
scope : scope
},process.env.SEED,{expiresIn : expiresin }); //se genera el JWT y
se se agregan a su payload algunos atributos que consideramos se
utilizaran en el API

var tokenResponse = {
access_token: access_token,
token_type: 'bearer',
expires_in: expiresin, //value in seconds
refresh_token: randtoken.uid(256),
refresh_token_expires_in: Number(process.env.RTEXT) , //value
in seconds
refresh_token_expires_in_date: Math.floor(Date.now() / 1000) +
Number(process.env.RTEXT) ,
scope: scope,
client: {clientId: clientId},
user: {username : username}
}
return tokenResponse;
}
OAuth 2.0

En el código, se obtiene la expiración del token y posteriormente, se genera el


JWT. Aquí se observa que se hace uso de las variables de entorno EXT, RTEXT y
SEED definidas en la sección Variables de entorno.

Una vez creado el JWT, se agrega como valor al campo access_token, se


llenan los demás campos con los parámetros de entrada de la función y otros se
generan en tiempo de ejecución, como lo es el refresh_token que es un
random String. Para esto último, se usa la librería rand-token para generar el
token y retornar el objeto. Para mayor información de la librería rand-token,
consulte el siguiente enlace: https://www.npmjs.com/package/rand-token

La función decodeClientCredentials toma el objeto req, que es la


solicitud que llega de algún ente externo al servidor, y busca si los parámetros
client_id y client_secret se enviaron dentro del header de la solicitud o si
se enviaron como parámetros del body. Se extraen de cualquiera de los dos casos
y se devuelven.

Como el client_secret es opcional, se inicializa como un string vacío el cual


más adelante se usará para validar si existe o no un valor en client_secret
en la base de datos.

let decodeClientCredentials = function(req) {

let clientId;
let clientSecret ='';

if (!req.headers.authorization ||
req.headers.authorization.indexOf('Basic ') === -1) {
//check the body
if(req.body.client_id){
clientId = req.body.client_id;
if(req.body.client_secret){
clientSecret = req.body.client_secret;
}
}
}else{
const base64Credentials = req.headers.authorization.split('
')[1];
const credentials = Buffer.from(base64Credentials,
'base64').toString('ascii');
[clientId, clientSecret] = credentials.split(':');
}
OAuth 2.0

return { id: clientId, secret: clientSecret };


};

3.3. Servicios MongoDB


Las funciones dentro de los servicios son de tipo async, esto porque los métodos
que provee mongoose retornan un promise. Por lo tanto, cuando se invoquen
las funciones de los servicios se tiene que anteponer la palabra await.
Al final de los archivos de servicios, se exportan las funciones para ser reconocidas
a la hora de importarlos en el archivo principal.

También se exportan los servicios que son los que realizan las peticiones a la base
de datos :
var userService= require("./mongo/service/mongoUser");
var clientService = require("./mongo/service/mongoClient");
var tokenService = require("./mongo/service/mongoToken");

Los servicios correspondientes a MongoDB están en el directorio <home


directory>/sistema_pdn/piloto_oauth2.0/mongo/service,
cada uno de ellos se describe en las siguientes secciones.

3.3.1. mongoUser
Dentro del archivo mongoUser se tienen las siguientes funciones:
● getUser(username, password). Esta función devuelve el usuario
correspondiente al username y el password recibidos en el método, en caso de
que existan en la base de datos

● getUserByUsername(username). Esta función devuelve el usuario


correspondiente al username

3.3.2. mongoClient
Dentro del archivo mongoClient se tiene la siguiente función:
● getClient (clientId).Esta función retorna el cliente correspondiente al
parámetro de entrada clientId
OAuth 2.0

var clientModel = require('./mongo/model/client');

async function getClient (clientId){


let client = await clientModel.findOne({clientId:
clientId}).exec();
return client;
}
module.exports.getClient = getClient;

3.3.3. mongoToken
Por último, se tiene el archivo mongoToken donde se tienen las siguientes
funciones:
● getTokenByRefresh (refresh_token). Esta función permite obtener el
documento token en base al parámetro de entrada refresh_token, esto es
usado en el flujo refresh token para la validación de los campos.

● removeTokenByRefresh (refresh_token). Esta función remueve el


token dado el parámetro de entrada refresh_token. Esta función se usa
una vez que se ha generado el nuevo token por el flujo refresh token. Se elimina
la entidad, ya que no debería ser funcional en ese punto del flujo.

3.4. Modelos y Esquemas


Los modelos y los esquemas generados con mongoose se encuentran en la ruta
<home directory>/sistema_pdn/piloto_oauth2.0/mongo

Los esquemas o “schemas” son la definición de la entidad, es decir, del


documento. Dentro de cada schema se definen los campos y el tipo de dato de
cada uno de ellos.

El modelo o “model” se genera con base al schema, y permite generar


operaciones CRUD hacia la base de datos.

var mongoose = require(‘mongoose’),


modelName = ‘client’,
schemaDefinition = require(‘../schema/’ + modelName),
schemaInstance = mongoose.Schema(schemaDefinition),
modelInstance = mongoose.model(modelName,
OAuth 2.0

schemaInstance);
module.exports = modelInstance;

En código anterior (/schema/client.js), el campo modelName es el nombre


de la base de datos dentro de MongoDB, de acuerdo a la documentación de
mongoose, para la creación del modelo el nombre debe estar en singular y en la
base de datos tiene que estar en plural (clients).

3.5. Lógica principal


La lógica principal se encuentra en la solicitud tipo POST /oauth/token. Dentro
de esta función se realizan las validaciones para la obtención del token, ya sea
grant type password o refresh token. El orden de las validaciones es el
siguiente:

Método Grant type password

1. Se obtienen los datos del cliente y se validan

2. Se obtiene el grant type enviado en el body de la solicitud y se valida


que sea de tipo password

3. Se obtienen el username y el password del body de la solicitud, con


estos datos se solicita a la base de datos el documento de ese usuario
asociado a esos campos

4. En caso de que el usuario exista, se obtienen los scopes enviados en el


body de la solicitud

5. Se validan los scopes asociados al usuario

6. Se genera el token

7. El token se almacena en la base de datos

8. Se retorna la respuesta en el formato descrito en el documento “Guía de


referencia protocolo de autorización”, Ref.[1]

Método Grant type refresh token

1. Se obtienen los datos del cliente y se validan


OAuth 2.0

2. Se obtiene el grant type enviado en el body de la solicitud y se valida


que sea de tipo refresh_token

3. Se obtiene el token por medio de la función refresh token

4. Se valida que sea el mismo cliente el que envía la solicitud al que está
asociado el token

5. Se valida la expiración del refresh token

6. Se obtiene el usuario por medio de la información asociada al token

7. En caso de que el usuario exista, se obtienen los scopes enviados en el


body de la solicitud

8. Se validan los scopes asociados al usuario

9. Se genera el nuevo token

10. El nuevo token se almacena en la base de datos

11. Se elimina el token anterior asociado al refresh token

12. Se retorna la respuesta en el formato descrito en el documento “Guía de


referencia protocolo de autorización”, Ref.[1].

3.6. Respuestas de error y causas

Status del
Mensaje de error causa
error

Credenciales del cliente Los parámetros del cliente no son


401
incorrectas correctos

Error en la contraseña del


401 El client_secret es incorrecto
cliente

Grant type no soportado 401 El grant type es incorrecto

El refresh token es invalido, El refresh token mandado no se


401
revisar sintaxis encuentra en la bd

El refresh token falta en la 422 No se mando el parámetro


OAuth 2.0

solicitud, verificar campo refresh_token en el body de la solicitud

El clientId enviado en la solicitud es


Clientid invalido, revise el
401 diferente al que se tiene asociado al
campo
token

El refresh token ha expirado 401 El refresh token expiró

Error en las credenciales del Credenciales inválidas por parte del


401
usuario, verificar los datos usuario

No se enviaron correctamente Faltan campos del usuario


422
los parámetros del usuario proporcionados en la solicitud

Parámetros de cliente enviados


401 Falta el client id en la solicitud post
incorrectamente

Falta el parámetro scope y el usuario si


Scope no proporcionado 422
tiene scopes asociados

Scope no válido 422 Los scopes que se manda son inválidos

4. Glosario
El glosario general se incluye en el anexo Guía de ayuda, Ref.[4].

5. Referencias
Ref. Nombre del documento

1 Guía de referencia protocolo de autorización

2 Instalación

3 Generador

4 Anexo

También podría gustarte