O uso de APIs OAuth fornecidas por aplicativos de terceiros, como o Google+, para fazer login no seu aplicativo móvel pode proporcionar uma experiência agradável aos usuários na primeira vez. Eles podem fazer login com uma conta que já conhecem e confiam e preencher o perfil com os dados que inseriram no Google+. Neste tutorial, você aprenderá a:
- Escreva um aplicativo Node.js para lidar com a autenticação com o Sync Gateway.
- Use a API REST do administrador do Couchbase Sync Gateway para criar usuários e sessões.
- Integre o Google Sign-In a um aplicativo iOS escrito com Swift 2.
- Crie um aplicativo iOS simples em Swift para testar o novo endpoint de login e replicar alguns documentos.
O projeto final pode ser encontrado em GitHub.
![]()
Pré-requisitos
Os pré-requisitos para este tutorial são:
- Node.js
- Xcode 7+ (você usará o Swift 2 para criar o aplicativo de amostra)
Primeiros passos
Faça o download do Sync Gateway no link abaixo e descompacte o arquivo:
https://www.couchbase.com/nosql-databases/downloads
Em um novo arquivo chamado sync-gateway-config.json, cole o seguinte:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "log": ["*"], "databases": { "simple-login": { "server": "walrus:", "users": { "GUEST": { "disabled": true } }, "sync": ` function(doc, oldDoc) { channel(doc._id); access(doc.user_id, doc._id); } ` } } } |
Nesse arquivo de configuração, você está criando um banco de dados chamado login simples e usando a função Sync para mapear cada documento para um canal diferente e conceder a um usuário acesso ao canal (o nome do usuário é armazenado no user_id do documento).
Inicie o Sync Gateway com o seguinte comando:
|
1 |
$ ~/Downloads/couchbase-sync-gateway/bin/sync_gateway sync-gateway-config.json |
Proxy reverso para gateway de sincronização
Com o Sync Gateway em execução, você pode mudar seu foco para a criação do App Server para lidar com a autenticação entre o Google e o Sync Gateway.
Você usará o popular Expresso para tratar a solicitação de criação de um usuário e o módulo solicitação para fazer proxy de todos os outros tráfegos para o Sync Gateway.
Instale os seguintes módulos do Node.js:
|
1 |
$ npm install express body-parser request --save |
Crie um novo arquivo chamado servidor.js e adicione o seguinte:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// 1 var express = require('express') , bodyParser = require('body-parser') , request = request('request').defaults({json: true}); // 2 var app = express(); app.use('/google_signin', bodyParser.json()); app.post('/google_signin', function (req, res) { // TODO: handle login request }); // 3 app.all('*', function (req, res) { var url = 'https://0.0.0.0:4984' + req.url; req.pipe(request(url)).pipe(res); }); // 4 var server = app.listen(8000, function () { var host = server.address().address; var port = server.address().port; console.log('App listening at https://%s:%s', host, port); }); |
Aqui estão as diferentes coisas que estão acontecendo:
- Requer o módulo Node.js que você instalou anteriormente.
- Instanciar uma nova instância do express e usar o bodyParser middleware apenas para o /google_signin ponto final.
- Proxy de todas as outras solicitações para o Sync Gateway.
- Inicie o servidor da Web Node.js na porta 8000.
Inicie o servidor com $ node server.js e aberto https://localhost:8000 em seu navegador. Você verá a mensagem de boas-vindas do Sync Gateway:

Do Google SignIn para sincronizar sessões do Gateway
Com o proxy reverso instalado, agora você pode adicionar algum código para tratar a solicitação do Google SignIn e retornar as credenciais da sessão:

Algumas coisas estão acontecendo nesse diagrama:
- Preto envia o ID de usuário do Google para o App Server.
- Azul verifica se existe um usuário no Sync Gateway com esse ID de usuário.
- Laranja cria o usuário se ele ainda não existir (normalmente, na primeira vez em que o usuário faz login com o Google no seu aplicativo).
- Verde cria uma sessão, a resposta conterá credenciais de sessão que podem ser passadas para o aplicativo cliente iOS para replicações push/pull. Todos os SDKs do Couchbase Lite têm um método para especificar as credenciais de sessão a serem usadas nas replicações push/pull.
No /google_signin adicione o seguinte:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
/** URL of the Sync Gateway instance running locally */ var stringURL = 'https://0.0.0.0:4985/simple-login'; /** Given the name of a user that exists in Sync Gateway, create a new session */ var sessionRequest = function (name, callback) { return request({ method: 'POST', url: stringURL + '/_session', json: true, body: { name: name } }, callback); }; var json = req.body; var name = json.auth_provider + '-' + json.user_id.toString(); request /** Check if the user already exists */ .get(stringURL + '/_user/' + name) .on('response', function (userExistsResponse) { if (userExistsResponse.statusCode === 404) { /** If the user doesn't exist, create one with the Google user ID as the name */ return request .put({ url: stringURL + '/_user/' + name, json: true, body: { name: name, password: Math.random.toString(36).substr(2) } }) .on('response', function (createUserResponse) { if (createUserResponse.statusCode === 201) { /** If the user was created successfully, create the session */ sessionRequest(name, function (sessionError, sessionResponse, body) { res.send(body); }); } }); } /** The user already exists, simply create a new session */ sessionRequest(name, function (sessionError, sessionResponse, body) { res.send(body); }); }); |
Reinicie o aplicativo Node.js e execute a seguinte solicitação curl para registrar um novo usuário:
|
1 2 3 4 5 6 7 8 9 10 11 |
$ curl -vX POST -H 'Content-Type: application/json' https://localhost:8000/google_signin -d '{"user_id": "123", "auth_provider": "google"}' // Response { "session_id":"8520c19159a4154abf5fb9b9003ff9677e035929", "expires":"2015-10-13T12:48:05.879325313+01:00", "cookie_name":"SyncGatewaySession" } |
Na próxima seção, você criará um aplicativo iOS simples com o Swift 2 para usar a nova funcionalidade do seu App Server.
Swift Time: tela de login simples para iOS
Vá para o Xcode e crie um novo projeto com a tag Aplicativo de visualização única modelo:

Usaremos o Cocoapods para instalar dependências neste projeto. Feche o projeto Xcode e, na linha de comando, execute Inicialização do pod $ para migrar seu projeto para o uso de Cocoapods. Abra o arquivo Podfile e adicione as declarações:
|
1 2 |
pod 'Google/SignIn' pod 'couchbase-lite-ios' |
Executar Instalação do pod $ e abra o SimpleLogin.xcworkspace que foi gerado. Em seguida, você adicionará um cabeçalho de ponte para acessar os SDKs do Google SignIn e do CouchbaseLite que usam Objective-C a partir do seu código Swift. No navegador de projetos do Xcode, clique com o botão direito do mouse em SimpleLogin e selecione Novo arquivo.... Escolha o modelo Header File e chame-o de bridging-header.h. Adicione as seguintes instruções de importação:
|
1 2 |
#import <Google/SignIn.h> #import <CouchbaseLite/CouchbaseLite.h> |
Agora você precisa informar ao Xcode para usar esse arquivo. No arquivo SimpleLogin alvo, selecione o Configurações de construção e role para baixo até a guia Cabeçalho de ponte em Objective-C. Adicione este caminho de arquivo:
SimpleLogin/bridging-header.h
Arquivo de configuração de login do Google
Antes de poder usar o SDK de login em seu aplicativo, você precisará criar um novo projeto no Google Developer Console e gerar um ID de cliente. Felizmente para nós, isso pode ser feito automaticamente com o seguinte link:
https://developers.google.com/mobile/add?platform=ios&cntapi=signin&cntapp=Simple%20Login&cntpkg=com.couchbase.SimpleLogin
Na página acima, clique no botão Escolha e configure serviços e você será levado a uma nova página na qual poderá ativar o Login do Google. A partir daí, clique em Gerar arquivos de configuração e faça o download do novo arquivo plist.
Importação GoogleServer-Info.plist em seu projeto Xcode:

Adição de esquemas de URL ao seu projeto
O Google Sign-In exige que dois esquemas de URL personalizados sejam adicionados ao seu projeto. Para adicionar os esquemas personalizados:
- Abra a configuração do projeto: clique duas vezes no nome do projeto na visualização em árvore à esquerda. Selecione seu aplicativo na seção METAS e, em seguida, selecione a seção Informações e expanda a guia Tipos de URL seção.
- Clique no botão + e adicione um esquema de URL para seu ID de cliente invertido. Para encontrar esse valor, abra o arquivo
GoogleService-Info.pliste procure o arquivo de configuraçãoREVERSED_CLIENT_IDchave. Copie o valor dessa chave e cole-o no campo Esquemas de URL na página de configuração. Deixe os outros campos em branco. - Clique no botão + e adicione um segundo esquema de URL. Esse esquema é o mesmo que o ID do pacote do seu aplicativo. Nesse caso, ele deve ser com.couchbase.SimpleLogin.
Quando concluída, sua configuração deve ser semelhante à seguinte (mas com os valores específicos do aplicativo):

Integração do Google Sign-In em seu aplicativo iOS
Agora que seu projeto está configurado corretamente, você pode começar a usar o SDK para adicionar o botão Login na interface do usuário e a lógica do aplicativo para recuperar as informações do usuário. Em AppDelegate.swiftdeclare que essa classe implementa a classe GIDSignInDelegate e adicione o seguinte no campo aplicativo:didFinishLaunchingWithOptions: método:
|
1 2 3 4 5 6 7 8 9 10 11 |
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Initialize sign-in var configureError: NSError? GGLContext.sharedInstance().configureWithError(&configureError) assert(configureError == nil, "Error configuring Google services: (configureError)") GIDSignIn.sharedInstance().delegate = self return true } |
Em seguida, implemente o aplicativo:openURL: do seu aplicativo delegado. O método deve chamar o handleURL do método GIDSignIn que tratará corretamente o URL que seu aplicativo recebe no final do processo de autenticação:
|
1 2 3 4 5 6 |
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool { return GIDSignIn.sharedInstance().handleURL(url, sourceApplication: sourceApplication, annotation: annotation) } |
No delegado do aplicativo, implemente o GIDSignInDelegate para lidar com o processo de login, definindo os seguintes métodos:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!, withError error: NSError!) { if (error == nil) { // Perform any operations on signed in user here. let userId = user.userID // For client-side use only! let idToken = user.authentication.idToken // Safe to send to the server let name = user.profile.name let email = user.profile.email // ... } else { println("(error.localizedDescription)") } } |
Adição do botão de login
Em seguida, você adicionará o botão Google Sign-In para que o usuário possa iniciar o processo de login. No view controller que gerencia a tela de login do seu aplicativo, faça com que a classe implemente a classe GIDSignInUIDelegado protocolo.
No view controller, substitua o método viewDidLoad para definir o delegado da interface do usuário do objeto GIDSignIn e (opcionalmente) para fazer login silenciosamente quando possível.
|
1 2 3 4 5 6 7 8 9 10 11 |
override func viewDidLoad() { super.viewDidLoad() GIDSignIn.sharedInstance().uiDelegate = self // Uncomment to automatically sign in the user. //GIDSignIn.sharedInstance().signInSilently() // TODO(developer) Configure the sign-in button look/feel // ... } |
Implementar o GIDSignInUIDelegado protocolo:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Implement these methods only if the GIDSignInUIDelegate is not a subclass of // UIViewController. // Stop the UIActivityIndicatorView animation that was started when the user // pressed the Sign In button func signInWillDispatch(signIn: GIDSignIn!, error: NSError!) { myActivityIndicator.stopAnimating() } // Present a view that prompts the user to sign in with Google func signIn(signIn: GIDSignIn!, presentViewController viewController: UIViewController!) { self.presentViewController(viewController, animated: true, completion: nil) } // Dismiss the "Sign in with Google" view func signIn(signIn: GIDSignIn!, dismissViewController viewController: UIViewController!) { self.dismissViewControllerAnimated(true, completion: nil) } |
Adicionar um GIDSignInButton ao seu storyboard ou arquivo XIB, ou instanciá-lo programaticamente. Para adicionar o botão ao seu storyboard ou arquivo XIB, adicione uma visualização e defina sua classe personalizada como GIDSignInButton.
Execute o aplicativo e você verá o botão com o estilo do Google e poderá fazer login:

Criação de uma sessão com o Sync Gateway
Em AppDelegate.swift, encontre o signIndidSignInForUserwithError e adicione o seguinte abaixo do código existente:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// 1 let loginURL = NSURL(string: "https://localhost:8000/google_signin")! // 2 let session = NSURLSession.sharedSession() let request = NSMutableURLRequest(URL: loginURL) request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.HTTPMethod = "POST" // 3 var properties = [ "user_id": userId, "auth_provider": "google" ] let data = try! NSJSONSerialization.dataWithJSONObject(properties, options: NSJSONWritingOptions.PrettyPrinted) // 4 let uploadTask = session.uploadTaskWithRequest(request, fromData: data, completionHandler: { (data, response, error) -> Void in // 5 let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! Dictionary<String, AnyObject> print("(json)") // TODO: pull/push replications with authenticated user }) uploadTask.resume() |
Veja o que está acontecendo acima:
- O URL de login no App Server em execução local.
- Criar uma instância de solicitação.
- Serialize as propriedades que contêm o ID de usuário do Google como JSON a ser enviado na solicitação.
- Enviar solicitação POST.
- Objeto de resposta que contém as credenciais da sessão do Sync Gateway
OBSERVAÇÃO: Antes de executar o aplicativo, certifique-se de desativar a segurança do App Transport, pois o App Server não está usando HTTPS. Abra o aplicativo Info.plist e adicione o seguinte:
|
1 2 3 4 |
NSAppTransportSecurity NSAllowsArbitraryLoads |
Compilar e executar. Observe a resposta do App Server no depurador do Xcode:

Por fim, você adicionará o código do Couchbase para iniciar uma replicação pull com os detalhes da sessão. Em AppDelegate.m, adicione o método startReplications:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
func startReplications(sessionInfo: Dictionary<String, String>) { // 1 let dateString = sessionInfo["expires"]! let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" let date = dateFormatter.dateFromString(dateString)! // 2 let manager = CBLManager.sharedInstance(); let database = try! manager.databaseNamed("simple-login") // 3 let syncGatewayURL = NSURL(string: "https://localhost:8000/simple-login")! let pull = database.createPullReplication(syncGatewayURL) pull?.continuous = true // 4 pull?.setCookieNamed(sessionInfo["cookie_name"]!, withValue: sessionInfo["session_id"]!, path: "/", expirationDate: date, secure: false) pull?.start() } |
Chame esse método na chamada de retorno do uploadTask que você adicionou na etapa anterior.
E pronto! Agora você tem uma replicação pull em execução para o usuário com o nome google-{userID}. Você pode testar se o acesso está funcionando adicionando um documento com o seguinte comando (substitua o ID de usuário do Google pelo de um usuário já conectado):
|
1 2 3 4 |
$ curl -vX POST -H 'Content-Type: application/json' https://localhost:4985/simple-login/ -d '{"_id": "1234", "user_id": "google-102898171485172449137"}' |
Vá até a guia Usuários na interface do usuário do administrador em https://localhost:4985/_admin/db/simple-login/users e observe que o usuário google-102898171485172449137 agora tem acesso ao canal 1234:

Para onde ir a partir de agora
Parabéns! Você aprendeu a usar o Google SignIn com o Couchbase Mobile para criar uma experiência agradável e sincronizar documentos de acordo com o ID do usuário conectado.
Sinta-se à vontade para compartilhar seus comentários, descobertas ou fazer perguntas nos comentários abaixo ou nos fóruns. Falamos com você em breve!