quarta-feira, 21 de janeiro de 2015

Exemplo de Autenticação em Node.JS - Autenticação via Google

Demais posts desta série:


Olá a todos,

Continuando nossa série de posts sobre autenticação utilizando Node.JS, vamos adicionar à nossa aplicação o login via Google. Este post é naturalmente mais curto que os demais, pois se trata de atualizações de código para um novo login. Já faremos as atualizações para suportar os múltiplos logins e união de contas.

Lembrando que o projeto completo está disponível aqui, e este tutorial foi baseado neste  excelente link.

Primeiro, precisaremos do nosso ID e token de acesso. Acessando a página do Google Cloud Platform, e fazendo o seu login do google, chegamos a seguinte página:


A criação do projeto não possui mistérios. Após a criação, a página será redirecionada para a página do projeto. No lado esquerdo, acesse APIs e Autenticação > Credenciais. Em seguida, na área destinada ao OAuth, clique em "Criar um novo ID de cliente". No pop-up que se abrirá, escolha a opção "Aplicativo da Web", e clique em "configurar tela de consentimento". A tela seguinte, é para configurar como será a tela de autorização de login. Só coloquei as opções padrão (nome do projeto, e-mail e URL).

Após salvar as configurações da tela de autorização, voltaremos para o pop-up para configurarmos as URLs de origem de de callback. Para este login, utilizaremos as seguintes URLs/rotas:

  • /google/connect (URL de redirecionamento)
  • /google/callback (URL de callback da tela do google para nossa aplicação)
  • /google/link (URL de união de logins do google a uma conta já existente)
  • /google/unlink (URL de remoção do login do google da nossa conta).
A URL de origem, para o google é a URL principal da aplicação, e a URL de callback especificamos acima. Quando tudo estiver preenchido, o pop-up deve ficar assim:


Após clicar no botão azul, copie o Client ID e o Client Secret e coloque no arquivo config/config.js, como espeficificado:

google:{
    consumer_key: 'seu_client_id_aqui',
    consumer_secret: 'sua_chave_secreta_aqui',
    callback_url:'http://127.0.0.1:3000/google/callback',
},

Em seguida, vamos fazer as alterações de praxe. Primeiro, instalamos o módulo do passport para comunicação do google:

npm install --save passport-google-oauth

Em seguida, atualizamos o nosso modelo (models/User.js)....

google:{
    id:String,
    token:String,
    email:String,
    name:String,
},

.... e o arquivo lib/passport.js com a nossa nova estratégia:

...

var GoogleStrategy=require('passport-google-oauth').OAuth2Strategy;

...

passport.use(new GoogleStrategy({
        clientID:config.secret.google.consumer_key,
        clientSecret:config.secret.google.consumer_secret,
        callbackURL:config.secet.google.callback_url,
        passReqToCallback:true,
    }, function(req, token, refreshToken, profile, done){
        process.nextTick(function(){
            if(!req.user){
                User.findOne({'auth.google.id': profile.id}, function(err,user){
                    if(err) return done(err);
                    
                    if(user){
                        return done(null, user);
                    }else{
                        var newUser=new User();
                        newUser.auth.google.id=profile.id;
                        newUser.auth.google.token=token;
                        newUser.auth.google.email=profile.emails[0].value;
                        newUser.auth.google.name=profile.displayName;
                        
                        newUser.save(function(err){
                            if(err) return done(err);
                            
                            return done(null, newUser);
                        });
                    }
                });
            }else{
                var _user=req.user;
                
                _user.auth.google.id=profile.id;
                _user.auth.google.token=token;
                _user.auth.google.email=profile.emails[0].value;
                _user.auth.google.name=profile.displayName;
                
                _user.save(function(err){
                    if(err) return done(err);
                    
                    return done(null, _user);
                });
            }
        });
    }));

Em seguida, configuramos as rotas...

    /* GOOGLE AUTH */
    
    '/google/connect':{
        controller:'LoginController',
        action:'googleConnect',
    },
    
    '/google/callback':{
        controller:'LoginController',
        action:'googleCallback',
    },
    
    '/google/link':{
        controller:'LoginController',
        action:'googleLink',
        policy:'isAuthenticated',
    },
    
    '/google/link/callback':{
        controller:'LoginController',
        action:'googleLinkCallback',
        policy:'isAuthenticated',
    },
    
    '/google/unlink':{
        controller:'LoginController',
        action:'googleUnlink',
        policy:'isAuthenticated',
    },

... e o controller:

    googleConnect:passport.authenticate('google'),
    
    googleCallback: passport.authenticate('google'{
        successRedirect:'/dashboard',
        failureRedirect:'/',
    }),
    
    googleLink: passport.authorize('google', {scope:['profile', 'email']}),
    
    googleLinkCallback: passport.authorize('google', {
        successRedirect:'/dashboard',
        failureRedirect:'/',
    }),
    
    googleUnlink: function(req,res){
        var user=req.user;
        user.auth.google.token=undefined;
        user.auth.google.id=undefined;
        user.save(function(err){
            if(err) throw err;
            
            res.redirect('/dashboard');
        });
    },

Para finalizar, ajustamos o arquivo views/dashboard.hbs...

           <!--Google Information-->
           <div class="col-sm-6">
                <div class="well">
                    <h3 class="text-danger"><span class="fa fa-google-plus"></span> Twitter</h3>
                    {{#if user.auth.google.id}}
                        <p>
                            <strong>id</strong>: {{user.auth.google.id}}<br/>
                            <strong>token</strong>: {{user.auth.google.token}}<br/>
                            <strong>email</strong>: {{user.auth.google.email}}<br/>
                            <strong>name</strong>: {{user.auth.google.name}}<br/>
                        </p>
                        <a href="/google/unlink" class="btn btn-danger">Desconectar</a>
                    {{else}}
                        <a href="/google/link" class="btn btn-danger">Conectar ao Twitter</a>
                    {{/if}}
                </div>
            </div>

... E a página principal:

<a href="/google/connect" class="btn btn-danger"><span class="fa fa-google-plus"></span> Google</a>

O resultado final pode ser visto nas imagens abaixo:

Página inicial
Dashboard


Com isso, finalizamos a autenticação para o Google. No próximo post (último da série), veremos como realizar a autenticação via Facebook.

Inté.


Demais posts desta série:

Nenhum comentário:

Postar um comentário