Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

P3rukao

Criar API com autenticação

Recommended Posts

Galera,

 

preciso criar uma aplicação com cURL, que acesse determinada action do meu site, e devolva por exemplo, os valores em XML. Essa aplicação teria que ter um tipo de autenticação, como informando uma string (TOKEN) que cada cliente (que fosse cadastrado em meu sistema) teria. Seria algo semelhante com o oAuth do Twitter, mas eu já pesquisei (muito), e não consegui usar esse oAuth de forma personalizada para o meu site.

 

Eu sei como recuperar os dados com cURL. Também sei ler o arquivo XML. O que não sei como fazer é essa parte da autenticação.

 

Essa aplicação é necessária, pois alguns sites de clientes meus, utilizam um serviço compartilhado de meu site (serviço de notícias, por exemplo), mas em alguns desses sites, o servidor não está conectando com o banco de dados, e assim, não consegue recuperar as informações.

 

Imagino que acessando essas informações com o cURL, eu possa poupar um pouco o banco de dados, salvando em cache o arquivo recuperado (XML).

 

Alguém sabe como posso começar a fazer esse sistema?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Porque não faz algo mais simples ? quando você cadastra um cliente, gera um token aleatório pra ele, daí na hora que ele enviar a requisição para um serviço que recupere as notícias por exemplo, você procura no banco se existe um token pra esse cliente, se existir, libera o xml ..

 

Ele pode passar esse token através de um parâmetro na url, algo como:

http://seusite.com/service?auth={TOKEN}&service=notices

Compartilhar este post


Link para o post
Compartilhar em outros sites

o mais correto seria utilizar soap q ja tem recursos de autenticacao...porem você tera q estudar muita coisa: webservices, soap, xml..wsdl...

 

Sim e não, SOAP vai dificultar ainda mais o que ele tem que fazer, quando poderia resolver simplesmente da forma que falei, e na verdade, a autenticação feita no WSDL não é grandes coisas, se não me engano os meios fornecidos são de autenticação interna.

Compartilhar este post


Link para o post
Compartilhar em outros sites

mas se ele vai criar uma API para terceiros, o ideal nao eh soap? se fosse algo interno at concordo com curl...mas pra terceiros ?

 

Certo, então mostre a ele um exemplo de autenticação com SOAP da forma que ele quer.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Concordo com o Andrey.

 

É uma solução simples e fácil, logo, pouparia performace no Banco de Dados, já que os dados seriam mostrados como XML ou...

 

Imprimir um jSON com PHP e retorná-los para os seus clientes como Objeto Javascript, mas essa opção é mais... Trabalhosa! :upset:

 

SOAP para uma aplicação dessa? Eeerk...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Concordo com o Andrey.

 

É uma solução simples e fácil, logo, pouparia performace no Banco de Dados, já que os dados seriam mostrados como XML ou...

 

Imprimir um jSON com PHP e retorná-los para os seus clientes como Objeto Javascript, mas essa opção é mais... Trabalhosa! :upset:

 

SOAP para uma aplicação dessa? Eeerk...

 

SOAP é uma opção sim. Por que não seria? Desempenho?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Certo, então mostre a ele um exemplo de autenticação com SOAP da forma que ele quer.

 

eu nao sei tudo, por isso eu lhe perguntei...gostaria de saber a resposta de alguem mais experiente, at pq eu nunca fiz isso, sempre li a respeito...

Compartilhar este post


Link para o post
Compartilhar em outros sites

SOAP é, de fato, uma opção para o que quero fazer. Já havia estudado essa opção, mas ele é, como vocês mesmo disseram, muito complicado de se implementar. Pelo menos eu não consegui fazer de primeira nada de util.

 

Demorei um pouquinho pra entender, mas acho que essa sua dica resolve o problema Andrey Knupp. Eu já havia pensado em fazer assim, mas com tanta coisa na cabeça, essa idéia estava confusa.

 

A idéia aqui não é fazer um Twitter da vida, mas quanto mais próximo possível de sua API (como segurança, rapidez e flexibilidade) melhor.

 

Obrigado a todos pelas dicas... Mas se alguém souber de algum outro método "comprovadamente eficaz" de se fazer essa aplicação, por favor comente.

Compartilhar este post


Link para o post
Compartilhar em outros sites

SOAP é uma opção sim.

 

Claro que é uma opção, o está correto ao sugeri-la! O único erro dele (do Igor) foi afirmar que é o mais correto.

 

muito complicado de se implementar.

 

Também não é complicado de se implementar.

 

1. Criação da interface, no caso do SOAP chama-se WSDL:

 

service.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:im="urn:com.imasters/forum"
			  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
			  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
			  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
			  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
			  name="news"
			  targetNamespace="urn:com.imasters/forum">

<wsdl:types>
	<xsd:schema targetNamespace="urn:com.imasters/forum">
		<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />

		<xsd:element name="datetime" type="xsd:dateTime" nillable="true" />
		<xsd:element name="feed" type="im:ArrayOfTopic" />
		<xsd:element name="authentication" type="im:User"/>

		<xsd:complexType name="ArrayOfTopic">
			<xsd:complexContent>
				<xsd:restriction base="soapenc:Array">
					<xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="im:Topic" />
				</xsd:restriction>
			</xsd:complexContent>
		</xsd:complexType>

		<xsd:complexType name="Topic">
			<xsd:sequence>
				<xsd:element name="title" type="xsd:string" />
				<xsd:element name="datetime" type="xsd:dateTime" />
				<xsd:element name="content" type="xsd:normalizedString" />
			</xsd:sequence>
		</xsd:complexType>

		<xsd:complexType name="User">
			<xsd:sequence>
				<xsd:element name="name" type="xsd:normalizedString" />
				<xsd:element name="pswd" type="xsd:normalizedString" />
				<xsd:element name="token">
					<xsd:simpleType>
						<xsd:restriction base="xsd:normalizedString">
							<xsd:length value="40"/>
						</xsd:restriction>
					</xsd:simpleType>
				</xsd:element>
			</xsd:sequence>
		</xsd:complexType>
	</xsd:schema>
</wsdl:types>

<wsdl:message name="authenticationHeader">
	<wsdl:part element="im:authentication" name="authentication"/>
</wsdl:message>

<wsdl:message name="getNewsRequest">
	<wsdl:part element="im:datetime" name="request" />
</wsdl:message>
<wsdl:message name="getNewsResponse">
	<wsdl:part element="im:feed" name="response" />
</wsdl:message>

<wsdl:portType name="service">
	<wsdl:operation name="getNews">
		<wsdl:input message="im:getNewsRequest" />
		<wsdl:output message="im:getNewsResponse" />
	</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="serviceSOAP" type="im:service">
	<soap:binding style="document"
				  transport="http://schemas.xmlsoap.org/soap/http" />

	<wsdl:operation name="getNews">
		<soap:operation soapAction="urn:com.imasters/forum/getNews" />
		<wsdl:input>
			<soap:header use="literal"
						 part="authentication"
						 message="im:authenticationHeader"
						 wsdl:required="true"/>

			<soap:body use="literal" />
		</wsdl:input>
		<wsdl:output>
			<soap:body use="literal" />
		</wsdl:output>
	</wsdl:operation>
</wsdl:binding>

<wsdl:service name="service">
	<wsdl:port binding="im:serviceSOAP" name="serviceSOAP">
		<soap:address location="http://seu-dominio.com/service.php" />
	</wsdl:port>
</wsdl:service>
</wsdl:definitions>

 

O WSDL define as operações do serviço e também as entradas e saídas, veja o detalhe da entrada na operação getNews:

 

<wsdl:input>
<soap:header use="literal"
			 part="authentication"
			 message="im:authenticationHeader"
			 wsdl:required="true"/>

<soap:body use="literal" />
</wsdl:input>

 

O serviço fica assim:

 

Service.php

<?php
require_once 'Topic.php';
require_once 'User.php';

class Service {
/**
 * Autenticação do usuário.
 * @param	User $request Usuário que está utilizando o webservice.
 */
public function authentication( User $request ) {
	// TODO: Regras de negócio para validação da autenticação
	if ( $request->getName() !== 'usuario' ||
		 $request->getPswd() !== 'senha' ||
		 $request->getToken() !== sha1( 'token' ) ){

		throw new SoapFault( 'AUTH' , 'Não autenticado' );
	}
}

/**
 * Recupera os tópicos de notícias.
 * @param	string $request Data no formato YYYY-MM-DDTHH:MM:SS
 * @return	array[Topic]
 */
public function getNews( $request ) {
	//TODO: Utilizar a model já existente para recuperar as notícias.
	return array( new Topic() , new Topic() );
}
}

 

Perceba que foram utilizadas duas entidades, Topic e User:

 

Topic.php

<?php
class Topic {
/**
 * @var	string
 */
private $title;

/**
 * @var	string
 */
private $datetime;

/**
 * @var	string
 */
private $content;

/**
 * @return	string
 */
public function getTitle() {
	return $this->title;
}

/**
 * @return	string
 */
public function getDatetime() {
	return $this->datetime;
}

/**
 * @return	string
 */
public function getContent() {
	return $this->content;
}

/**
 * @param	string $title
 */
public function setTitle($title) {
	$this->title = $title;
}

/**
 * @param	string $datetime
 */
public function setDatetime($datetime) {
	$this->datetime = $datetime;
}

/**
 * @param	string $content
 */
public function setContent($content) {
	$this->content = $content;
}
}

 

User.php

<?php
class User {
/**
 * @var	string
 */
private $name;

/**
 * @var	string
 */
private $pswd;

/**
 * @var	string
 */
private $token;

/**
 * @return	string
 */
public function getName() {
	return $this->name;
}

/**
 * @return	string
 */
public function getPswd() {
	return $this->pswd;
}

/**
 * @return	string
 */
public function getToken() {
	return $this->token;
}

/**
 * @param	string $name
 */
public function setName($name) {
	$this->name = $name;
}

/**
 * @param	string $pswd
 */
public function setPswd($pswd) {
	$this->pswd = $pswd;
}

/**
 * @param	string $token
 */
public function setToken($token) {
	$this->token = $token;
}
}

 

Para configurar o servidor SOAP é bem simples:

 

service.php

[

<?php
require_once 'Service.php';
require_once 'User.php';

$server = new SoapServer( 'service.wsdl'  , array(
'trace'			=> true,
'exceptions'	=> true,
'style'			=> SOAP_DOCUMENT,
'use'			=> SOAP_LITERAL,
'soap_version'	=> SOAP_1_1,
'encoding'		=> 'UTF-8',
'classmap'		=> array(
	'User'		=> 'User',
)
) );

$server->setObject( new Service() );
$server->handle();

 

Perceba que esse service.php é o que está configurado no WSDL, lá em soapaddress:

 

<soap:address location="http://seu-dominio.com/service.php" />

 

Bom, com isso você tem um web service SOAP pronto, para seu clientes utilizarem isso basta fazerem:

 

client.php

<?php
require_once 'Topic.php';

//Configura o client
$client = new SoapClient( 'http://127.0.0.3/dg/service.wsdl' , array(
'trace'			=> true,
'exceptions'	=> true,
'style'			=> SOAP_DOCUMENT,
'use'			=> SOAP_LITERAL,
'soap_version'	=> SOAP_1_1,
'encoding'		=> 'UTF-8',
'classmap'		=> array(
	'Topic'			=> 'Topic',
)
) );

//Configura a autenticação 
$client->__setSoapHeaders( new SoapHeader(
'urn:com.imasters/forum',
'authentication',
(object) array(
	'name' => 'usuario',
	'pswd' => 'senha',
	'token' => sha1( 'token' )
)
) );

//Recupera as notícias
try {
$news = $client->getNews();

print_r( $news );
} catch ( SoapFault $f ) {
//regras para manipulação do Soap Fault
}

 

Just simple!

 

O código do exemplo do servidor está em: https://github.com/netojoaobatista/soap

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vish! API RESTful é a solução.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vish! API RESTful é a solução.

 

Sou obrigado a concordar ..

 

Concordo plenamente.

 

Nesse caso específico, sim, é a solução. Mas alguém que discorda da implementação SOAP, consegue dizer o motivo de REST ser a solução para esse caso específico?

 

Já que concordam que RESTful é a solução, devem ter algum argumento que não seja mero "achismo".

 

:seta: Quem se habilita a apontar o motivo de REST ser a solução desse caso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom para mim pq seria um webservice simples e fazer em RESTful eh bem mais simples e bonito. Gostaria de saber quais APIs conhecidas como twitter, facebook, youtube, gmaps e cia usam SOAP, alguem sabe?

 

Bom para mim pq seria um webservice simples e fazer em RESTful eh bem mais simples e bonito. Gostaria de saber quais APIs conhecidas como twitter, facebook, youtube, gmaps e cia usam SOAP, alguem sabe?

 

Alguns links:

http://geeknizer.com/rest-vs-soap-using-http-choosing-the-right-webservice-protocol/

http://ajaxonomy.com/2008/xml/web-services-part-1-soap-vs-rest

http://www.devx.com/DevX/Article/8155

 

Esse aqui eh bom pois diz onde é melhor usar cada:

http://www.infoq.com/articles/rest-soap-when-to-use-each

Compartilhar este post


Link para o post
Compartilhar em outros sites

bem mais simples e bonito.

 

Bonito é uma questão pessoal, dessa forma não é um argumento válido.

 

Simples, bom, mapeie todas as URIs das requisições, implemente a autenticação utilizando certificados digitais ou 3 tokens e depois compare com a versão SOAP, você vai ver que não é tão simples assim.

 

Gostaria de saber quais APIs conhecidas como twitter, facebook, youtube, gmaps e cia usam SOAP, alguem sabe?

 

Existem várias APIs públicas, você citou apenas algumas. Posso citar algumas também:

 

PayPal :seta: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_soap_PayPalSOAPAPIArchitecture

ECT :seta: http://www.correios.com.br/webservices/

SERASA :seta: http://www.serasaexperian.com.br

Nfe :seta: http://www.sped.fazenda.pr.gov.br/modules/conteudo/conteudo.php?conteudo=69

 

Sendo assim, sou obrigado a discordar do motivo que você usou para discordar.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ta e por ue o SOAP eh melhor?

 

Soh o trampo de criar esse WSDL eh o trampo de criar o webservice inteiro em REST, ae vai do cara neh ;D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ta e por ue o SOAP eh melhor?

 

Quem disse que é melhor?

 

Veja na primeira frase do meu primeiro post que eu disse que o único erro do Igor foi dizer que era o mais correto: http://forum.imasters.com.br/topic/455759-criar-api-com-autenticacao/page__view__findpost__p__1803910

 

Veja também que eu disse várias vezes que nesse caso específico, REST é o mais adequado. Mas eu quero saber, daqueles que discordam da implementação SOAP, o motivo de acharem REST ser melhor, um motivo claro e direto, com foco exclusivamente técnico e que não seja baseado em "achismo".

Compartilhar este post


Link para o post
Compartilhar em outros sites

:seta: Quem se habilita a apontar o motivo de REST ser a solução desse caso?

 

Por ser mais fácil de implementar.

 

Na verdade, pelo que ele descreveu sobre o que quer fazer, é algo tão simples como validar uma chave recebida e a disponibilidade do serviço pra esta chave, só fazer a comparação lógica, e dar as respostas para o serviço solicitado.

 

Algo que pra mim, não passaria de uma função, isso conta a usabilidade também, da pessoa que ira utilizar o serviço..

 

Olha a forma que você utilizou somente para chamar o serviço, temos que pensar na pessoa que vai integrar isso ao website, claro que o provedor do serviço pode oferecer exemplos de uso, mas ainda sim é meio complicado pra alguns.

 

Simples, bom, mapeie todas as URIs das requisições, implemente a autenticação utilizando certificados digitais ou 3 tokens e depois compare com a versão SOAP, você vai ver que não é tão simples assim.

 

Nesse caso eu colocaria um bunker no servidor, seria mais simples huauauhauha, mas João, veja bem o token só serve pra identificar quem está utilizando o serviço e que é permitido a utilizar, se esses tokens ficam em um banco de dados e é validado na hora da requisição, não tem como alguém 'driblar' isso, até mesmo porque eu duvido muito que alguém esteja preocupado em fazer isso.

 

Colocar o serviço a sete chaves é a mesma coisa que você colocar 3 formulários pra fazer o login no fórum, o que iria acontecer ? ninguém ia usar.

 

No final das contas, dependendo do serviço que ele oferece, um SOAP acaba colocando mais pedras no caminho dele, enquanto algo parecido com REST ou um REST em si, seria bem mais fácil de implementar e usar.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.