======= API.sistemas- API de Serviços da UFRN ======= =====O que é a API.sistemas?===== É um canal de comunicação que tem como principal função disponibilizar os dados dos sistemas da UFRN para que seja possível proporcionar que entidades externas criem aplicações(independentes de plataforma) que utilizam tais dados. Os dados são disponibilizados no formato JSON, para ser de fácil consumação pelos usuários e aplicações serem independentes de plataforma e linguagem de programação. =====Tecnologias utilizadas===== ==== OAuth 2.0 ==== No intuito de possibilitar a utilização dos dados gerados nos seus sistemas, grandes empresas desenvolveram protocolos de autorização proprietários para permitir a criação de aplicações que acessassem suas APIs. A criação desses novos protocolos deve-se ao fato de que no modelo tradicional cliente-servidor o usuário precisa compartilhar suas credenciais com as aplicações para permitir que as mesmas utilizem seus dados, o que gera problemas de segurança, pois aplicações mal intencionadas poderiam utilizar a senha do usuário para acessar indevidamente os dados do mesmo. Entretanto, a criação de protocolos de autorização proprietários adicionou um custo, em razão de que um desenvolvedor precisaria aprender a implementar múltiplos protocolos para integrar diferentes provedores de APIs em sua(s) aplicação(ões). O //Open Authorization Protocol// (OAuth) surgiu como uma alternativa a isso, aparecendo como um protocolo de autorização aberto que objetiva padronizar a forma como aplicações acessam uma API para utilizar os dados do usuário. O OAuth 2.0 é uma evolução do protocolo OAuth e busca simplificar o desenvolvimento dos clientes provendo fluxos de autorização específicos para aplicações //web//, //desktop//, //mobile// e outros dispositivos. == Conceitos importantes == * **Autenticação**: processo de verificar a identidade de um usuário, em outras palavras, é o processo que verifica se um usuário é quem ele diz ser. * **Autenticação federada**: aplicações que dependem de outros serviços para verificar a identidade de usuários. * **Autorização**: processo de verificar se o usuário tem o direito de executar uma ação. * **Autorização delegada**: processo no qual o usuário concede permissão para uma pessoa ou aplicação realizar ações em seu nome. == Papéis == * //Resource owner//: entidade que tem a capacidade de conceder acesso a recursos protegidos. * //Resource server//: entidade que disponibiliza o recurso protegido. * //Client//: entidade que requisita o acesso ao recurso protegido. * //Authorization server//: entidade que autoriza clientes a acessar recursos protegidos. == Parâmetros importantes == * //client_id//: sequência única de caracteres que representa a identificação do cliente. * //client_secret//: sequência de caracteres que representa a “senha” do cliente. * //access_token//: sequência de caracteres que representam credenciais utilizadas para acessar recursos protegidos. * //refresh_token//: sequência de caracteres utilizadas para requisitar um novo //access_token//. * //redirect_uri//: página para onde o usuário deve ser redirecionado após a realização do login. * //response_type//: Deve assumir os valores: "code" para requisitar //authorization code// ou "token" para requisitar um //access token// no fluxo //Implicit//. * //grant_type//: Deve assumir os valores: 1) "authorization_code" no fluxo //Authorization code//; 2) "password" no fluxo //Resource Owner Password Credentials//; 3) "client_credentials" no fluxo //Client Credentials//; 4) "refresh_token" para requisitar um novo //token// de acesso. * //token_type//: tipo do //token// gerado. * //expires_in//: tempo de duração, em segundos, do //access_token//. * //scope//: define o escopo de acesso. * //username//: //login// do //resource owner//. * //password//: senha do //resource owner//. * //code//: //authorization code// enviado pelo //authorization server//. == Fluxos de autorização == * //Authorization code// Neste fluxo, o //client// redireciona o //resource owner// para que o mesmo realize autenticação no //authorization server// e, em seguida, autorize o //client// a utilizar seus recursos. Após o processo de autorização da aplicação, o //authorization server// envia um //authorization code// ao //client//. Em posse do código, o //client// requisita um //access token// passando o código recebido. O //authorization server// verifica o código e envia um //access_token// e um //refresh_token// ao //client//. Por fim, o //client// requisita os dados do //resource server// passando o //access token// recebido do //authorization server//. {{ :desenvolvimento:especificacoes:barramento_servicos:authorization_code.png?600 |}} * //Implicit// O fluxo de autorização implícito é uma simplificação do //authorization code//. Nele o //access token// é retornado ao //client// logo após o //resource owner// autorizá-lo a utilizar seus dados. E, em seguida, o //client// já pode requisitar os dados do recurso desejado no //resource server//. Nesse fluxo não há suporte para //refresh token// e, caso o //access token// criado para o //resource owner// expire, o fluxo de autorização precisa ser repetido para requisitar um novo //access token//. {{ :desenvolvimento:especificacoes:barramento_servicos:implict.png?500 |}} * //Resource Owner Password Credentials// Neste fluxo o //resource owner// informa seu //username// e //password// ao //client//, esse último usa essas informações para obter um //access token// do //authorization server//. Em posse, desse //token// o //client// já pode requisitar dados do //resource server//. Esse tipo de fluxo é recomendado somente no caso em que a aplicação é propriedade do desenvolvedor da API, isso se deve em virtude de o //resource owner// precisar informar suas credenciais ao //client//. {{ :desenvolvimento:especificacoes:password.png?500 |}} * //Client Credentials// Neste fluxo a aplicação envia suas credenciais ao //authorization server// e recebe um //access token// do mesmo. No fluxo //client credentials// não há suporte para //refresh token//, assim, quando o //token// expira a aplicação deve repetir o fluxo para obter um novo //access token//. {{ :desenvolvimento:especificacoes:client_credentials.png?400 |}} === REST === REST do inglês Representational State Transfer, em português Transferência de Estado Representacional. Trata-se de um modelo arquitetural que possui um conjunto de restrições aplicados a todo o sistema web, como: componentes, conectores e elementos de dados dentro de um sistema de hipermídia distribuído. É dispensável para essa tecnologia a sintaxe de implementação, já que pode ser aplicado em qualquer serviço web. Este que pode ser chamado de RESTful, caso atenda todas as restrições desse padrão de arquitetura. Essas restrições estão divididas em seis partes, são elas: * //Cliente-Servidor(Client-Server)//: Aqui traz-se o conceito de independência, onde existe separação entre o cliente e o servidor, o qual permite que servidores e clientes possam ser desenvolvidos independentemente sem que a comunicação entre eles sejam prejudicadas. * //Sem Estado (Stateless)//: Como próprio nome já diz, trata-se de uma comunicação sem estado, ou seja, o servidor não guarda nenhum estado de sessão do cliente, de forma que todo dado é obtido com as informações da requisição, trazendo assim mais visibilidade, segurança e escalabilidade. * //Cacheable//: A arquiteura REST permite que utilize-se serviços de armazenamento em cache das respostas dos servidores, porém é preciso trata-las para que os usuários não acessem dados obsoletos ou inapropriados. E um bom serviço de gerenciamento do cache pode trazer bastante eficiência nas comunicações com o servidor, já que muitas delas podem ser aproveitadas devido aos dados armazenados em cache. * //Sistema em Camadas (Layered System)//: O sistema em camadas permite que o sistema seja dividido em camadas com restrições, de modo que cada componente da aplicação só possa ter acesso direto com as camadas de sua ligação. Isso com o intuito de melhorar as requisições do usuário, de modo de seja mais filtrada e direcionada da forma mais segura possível. * //Interface Uniforme (Uniform Interface)//: Principal característica da arquitetura REST que foi designada para ser eficiente com grande numero de dados, trabalhando com um resultado equivalente apenas para a sua arquitetura. Existindo algumas estrições principais: as identificações de recursos que são identificadas na requisição, como as URI's; mensagens auto-descritivas onde cada mensagem possui toda a informação necessária para ser processada e hipermídia, o qual os clientes fazem transições de estado somente através de ações que são dinamicamente identificadas, por exemplo, hiperlinks em hipertextos. === JSON === Trata-se de uma modelagem de armazenamento de transmissão de arquivos de texto, oriundo do JavaScript, por isso significa JavaScript Obect Notation, mas que pode ser utilizado por diversas linguagens. É bastante simples, porém muito eficiente e poderoso, pois devido a sua forma compacta a sua transmissão e o 'parsing' da informação ocorrem de forma ágil. Algumas empresas já utilizam esse mecanismo, como a Google e a Yahoo, o que demonstra ser bastante eficientes, pois os dois trabalham com buscas e essa se trata de uma das melhores formas de se veicular a informação. Cada informação é definido por uma tupla, sendo um rótulo e o seu valor, podendo ser este valor campos string, inteiros, reais, booleanos, arranjos e objetos. Ex.: { “nome” : “Vinícius”, “idade” : 21, “altura” : 1.7, “estudante” : true, “interesses” : [“Development”, “Mobile”, “Web”, “Games”], “parentes” : [ { “nome” : “José”, “parentesco” : “pai” }, { “nome” : “Maria”, “parentesco” : “mãe” } ] } =====Autorização e autenticação na API===== Atualmente, a API de serviços da SINFO implementa e disponibiliza três dos quatro fluxos de autorização do OAuth 2.0 e o fluxo de //refresh_token//, os quais são mostrado abaixo. ===Client Credentials=== Esse fluxo foi implementado para ser usado por aplicações que queiram acessar os dados públicos dos sistemas da SINFO, com por exemplo: eventos, notícias, telefones, entre outros. Desse modo, aplicações com esse intuito, devem seguir os seguintes passos: - A aplicação faz uma requisição POST ao //authorization server// através da URL http://apitestes.info.ufrn.br/authz-server/oauth/token, passando o //client_id//, //client_secret// e //grant_type// como //QueryParam//. Ex: **POST** http://apitestes.info.ufrn.br/authz-server/oauth/token?client_id=AppId&client_secret=AppSecret&grant_type=client_credentials - O //authorization server// retorna à aplicação um //Json// contendo o //access_token//, //token_type//, //expires_in// e //scope//. Ex: { “access_token”: “000000000000000000000000000000000000”, “token_type”: “bearer”, “expires_in”: 7431095, “scope”: “read” } - Em posse dessas informações, a aplicação já pode acessar os dados disponibilizados pela API passando o //token// através do parâmetro //Authorization// no //HEADER// da requisição desejada. Ex: **GET** http://apitestes.info.ufrn.br/telefone-services/services/consulta/telefone/ccet **Authorization**: Bearer 000000000000000000000000000000000000 - Os dados da API são retornados para a aplicação. Ex.: [ { "idTelefone": 0, "localizacao": "string", "setor": "string", "descricao": "string", "numero": "string", "ramais": [ { "numero": "string", "descricao": "string" } ] } ] {{ :desenvolvimento:especificacoes:client_credentials_ufrn.png?600 |}} ===Authorization code=== Esse fluxo deve ser utilizado por aplicações que queiram acessar as informações privadas às contas de usuários dos sistemas SINFO, como por exemplo: turmas de um usuário, frequências de um discente, histórico de utilização de um usuário no restaurante universitário, etc. Assim, aplicações com esse propósito precisam seguir os seguintes passos: - O usuário inicia a interação com a aplicação. - A aplicação faz uma requisição **GET** ao //authorization server// através da URL http://apitestes.info.ufrn.br/authz-server/oauth/authorize, passando os parâmetros //client_id//, //response_type// e //redirect_uri// como //QueryParam//. Ex: **GET** http://apitestes.info.ufrn.br/authz-server/oauth/authorize?client_id=AppId&response_type=code&redirect_uri=http://enderecoapp.com.br/pagina - O usuário é redirecionado para o //authorization server//, o mesmo deve informar suas credenciais (//username//, //password//) na página de autenticação exibida e, em seguida, informar se autoriza a aplicação a utilizar seus dados. - O //authorization server// retorna o código de autorização à aplicação. - Em posse desse código, a aplicação pode usá-lo para obter um //access_token// para o usuário. Desse modo, ela realiza uma nova requisição, neste caso um **POST**, ao //authorization_server// através da URL http://apitestes.info.ufrn.br/authz-server/oauth/token, passando os parâmetros //client_id//, //client_secret//, //redirect_uri//, //grant_type// e //code// como //QueryParam//. Ex: **POST** http://apitestes.info.ufrn.br/authz-server/oauth/token?client_id=AppId&client_secret=AppSecret&redirect_uri=http://enderecoapp.com.br/pagina&grant_type=authorization_code&code=code - O authorization server retorna à aplicação um //Json// contendo o //access_token//, //token_type//, //refresh_token//, //expires_in// e //scope//. Ex: { “access_token”: “000000000000000000000000000000000000”, “token_type”: “bearer”, "refresh_token": "ffffffffffffffffffffffffffffffffffff" , “expires_in”: 7431095, “scope”: “read” } - - Em posse dessas informações, a aplicação já pode acessar os dados disponibilizados pela API passando o //token// através do parâmetro //Authorization// no //header// da requisição desejada. Ex: **GET** http://apitestes.info.ufrn.br/ensino-services/services/consulta/listavinculos/usuario **Authorization**: Bearer 000000000000000000000000000000000000 - Os dados da API são retornados para a aplicação. Ex.: { "docentes": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false, "siape": "string", "lotacao": "string" } ], "discentes": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false, "matricula": "string", "curso": "string", "status": 0, "anoIngresso": 0, "periodoIngresso": 0 } ], "docentesExterno": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false, "matricula": "string", "instituicao": "string" } ], "outros": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false } ], "id": 0, "all": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false } ] } {{ :desenvolvimento:especificacoes:authorization_code_ufrn.png?600 |}} ===Resource Owner Password Credentials=== Esse tipo de fluxo deve ser utilizado por aplicações que sejam de propriedade da própria SINFO e que necessitem dos dados privados a contas de usuários, em virtude de o OAuth 2.0 definir que no //Resource Owner Password Credentials// o usuário informa suas credenciais diretamente à aplicação. Logo, aplicações com essa característica precisam seguir os seguintes passos: - O usuário informa suas credenciais de acessso à aplicação (//username// e //password//). - A aplicação faz uma requisição **POST** ao //authorization server// através da URL http://apitestes.info.ufrn.br/authz-server/oauth/token, passando os parâmetros //client_id//, //client_secret//, //grant_type//, //username// e //password//. Ex: **POST** http://apitestes.info.ufrn.br/authz-server/oauth/token?client_id=AppId&client_secret=AppSecret&grant_type=password&username=loginUsuario&password=senhaUsuario - O authorization server retorna à aplicação um //Json// contendo o //access_token//, //token_type//, //refresh_token//, //expires_in// e //scope//. Ex: { “access_token”: “000000000000000000000000000000000000”, “token_type”: “bearer”, "refresh_token": "ffffffffffffffffffffffffffffffffffff" , “expires_in”: 7431095, “scope”: “read” } - Em posse dessas informações, a aplicação já pode acessar os dados disponibilizados pela API passando o novo //token// através do parâmetro //Authorization// no //header// da requisição desejada. Ex: **GET** http://apitestes.info.ufrn.br/ensino-services/services/consulta/listavinculos/usuario **Authorization**: Bearer 000000000000000000000000000000000000 - Os dados da API são retornados para a aplicação. Ex.: { "docentes": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false, "siape": "string", "lotacao": "string" } ], "discentes": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false, "matricula": "string", "curso": "string", "status": 0, "anoIngresso": 0, "periodoIngresso": 0 } ], "docentesExterno": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false, "matricula": "string", "instituicao": "string" } ], "outros": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false } ], "id": 0, "all": [ { "contemTurmas": false, "idUsuario": 0, "numero": 0, "id": 0, "ordem": 0, "ativo": false } ] } {{ :desenvolvimento:especificacoes:password_ufrn.png?600 |}} ===Refresh Token=== O fluxo de //refresh token// deve ser utilizado quando o //access_token// de um usuário expira em aplicações que utilizem os fluxos de autorização //authorization code// e //resource owner password credentials// disponibilizados pela API de serviços da SINFO. Assim, as mesmas devem seguir os seguintes passos: - A aplicação deve fazer uma requisição **POST** ao servidor de autorização através da URL http://apitestes.info.ufrn.br/authz-server/oauth/token, passando os parâmetros //client_id//, //client_secret//, //grant_type// e //refresh_token// como //QueryParam//. Ex: **POST** http://apitestes.info.ufrn.br/authz-server/oauth/token?client_id=AppId&client_secret=AppSecret&grant_type=refresh_token&refresh_token=ffffffffffffffffffffffffffffffffffff - O //authorization server// retorna à aplicação um //Json// contendo o //access_token//, //token_type//, //refresh_token//, //expires_in// e //scope//. Ex: { “access_token”: “111111111111111111111111111111111111”, “token_type”: “bearer”, "refresh_token": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" , “expires_in”: 7431095, “scope”: “read” } - Em posse dessas informações, a aplicação já pode acessar os dados disponibilizados pela API passando o //token// através do parâmetro //Authorization// no //header// da requisição desejada. Ex: **GET** http://apitestes.info.ufrn.br/telefone-services/services/consulta/telefone/ccet **Authorization**: Bearer 111111111111111111111111111111111111 - Os dados da API são retornados para a aplicação. Ex.: [ { "idTelefone": 0, "localizacao": "string", "setor": "string", "descricao": "string", "numero": "string", "ramais": [ { "numero": "string", "descricao": "string" } ] } ] {{ :desenvolvimento:especificacoes:refresh_token_ufrn.png?600 |}} ===== Exemplos de utilização ===== ====Android utilizando Authorization code==== Neste exemplo mostra-se a utilização do fluxo de autorização //authorization code// em uma aplicação Android. Desse modo, a primeira tela da aplicação contém as funcionalidades básicas da mesma (Logar, Obter dados e Sair). Como mostrado nos dois trechos de código que formam a mesma: * //activity_main.xml// * //content_main.xml//