带有量角器的Google身份验证 [英] Google Authentication with Protractor

查看:76
本文介绍了带有量角器的Google身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只能跟踪此链接来解决我的问题.我正在尝试使用量角器来运行e2e测试.这是我的第一次尝试,我喜欢它.但是,我的项目需要Google身份验证,然后通过身份验证,然后将其与数据库进行比较,以确保用户在项目中.我无法从stackoverflow帖子中弄清楚在最后一个答案中如何调用Google Auth页面对象demee.另外,第一人称要查找元素by.id('Email')和by.id('Passwd'),这可能是一个问题,因为我的Google身份验证正在另一个窗口中显示.所以我不确定如何用量角器调用它.这是在加载gapi后初始化$ window之后的一些代码:

I have only been able to track down this link to solve my problem. I am trying to use protractor to run e2e testing. This is my first go at it, and I like it. However my project requires Google Authentication, then once authenticated, I compare it to my database to make sure the user is in the project. I cannot figure out from the stackoverflow post how to call to the Google Auth page object demee is talking about in the last answer. Also the first person says to find element by.id('Email') and by.id('Passwd') which may be a problem, because my google auth is coming up in another window. So I am not sure how to call to that with Protractor. Here is some of my code after I initialize the $window once gapi is loaded:

.controller('ContainerController', ['$scope', '$rootScope', '$state','$window', '$location','employeeFactory', 'employeeTestFactory', function ($scope, $rootScope, $state, $window,$location, employeeFactory, employeeTestFactory) {
        $rootScope.callRequests=function(){};
        $rootScope.callInfo=function(){};
        if(typeof $rootScope.gapi !== "undefined")gapi.load('client:auth2', initClient);
        $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
            if(typeof $rootScope.gapi === "undefined") return;
            gapi.load('client:auth2', initClient);
        })
        $scope.$state = $state;
        $window.initGapi = function() {
            gapi.load('client:auth2', initClient);
            $rootScope.gapi = gapi;
        }
        $rootScope.calculateUsed = function(val){
            $rootScope.employee.timePending = $rootScope.employee.timePending = 0;
            var newTimeUsed = 0;
            angular.forEach(val, function(key, value){
                var td = key.timeDuration;
                if(key.timeState === "pending"){
                    $rootScope.employee.timePending += Number(td);
                }else{
                    newTimeUsed += Number(td);
                }
            });
            $rootScope.employee.totalTimeUsed = newTimeUsed;
        }

        $scope.employeeType = $rootScope.email = "";
        function initClient() {
            gapi.client.init({
                apiKey: 'AIzaSyDaMf0eviuFygt1hzwQz03a2k2lrLDnpIc',
                discoveryDocs: ["https://people.googleapis.com/$discovery/rest?version=v1"],
                clientId: '977491754644-954b83j2evmq65v6kchq4dsd9j0ud4vg.apps.googleusercontent.com',
                scope: 'profile'
            }).then(function () {                    gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);                    updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
                $scope.employee = [];
            });
        }

        function updateSigninStatus(isSignedIn) {
            if (isSignedIn) {
                getEmailAddress();
            }else{
                $state.go('app');
            }
        }

        $scope.handleSignInClick = function(event) {
            if(!gapi.auth2.getAuthInstance().isSignedIn.get()){
                gapi.auth2.getAuthInstance().signIn();
            }
        }

        $scope.handleSignOutClick = function(event) {
            if(gapi.auth2.getAuthInstance().isSignedIn.get()){
                gapi.auth2.getAuthInstance().signOut();
            }
        }

        function getEmailAddress() {
            gapi.client.people.people.get({
                resourceName: 'people/me'
            }).then(function(response) {

                $rootScope.email = response.result.emailAddresses[0].value;
                $rootScope.callRequests();
                $rootScope.callInfo();
        //Here is where I compare google to my db and route users back to main if not in db                employeeTestFactory.get($rootScope.email).then(function(message) {
                    if(typeof message.employeeid === "undefined"){
                        $state.go('app');
                    }else if($location.path() === "/"){
                        $state.go('app.employee');
                        $rootScope.employee = message;

                    }else{
                        $rootScope.employee = message;

                    }
                });

            }, function(reason) {
                console.log('Error: ' + reason.result.error.message);
            });
        }
    }])

    .controller('LoginController', ['$scope', '$state', '$window', '$http','$rootScope', '$timeout', 'GooglePlus', 'gapiService', function ($scope, $state, $window, $http, $rootScope, $timeout, GooglePlus, gapiService) {

        $scope.$state = $state;
        $scope.callme = function(){
            $scope.handleSignInClick();
        }


        // if it could not be loaded, try the rest of
        // the options. if it was, return it.

        var url;
        var windowThatWasOpened;

        $http.get("url").then(function(response) {
            url = response.data;
        });

        $scope.login = function() {
            windowThatWasOpened = $window.open(url, "Please sign in with Google", "width=500px,height=700px");
        }


        window.onmessage = function(e) {

            if(windowThatWasOpened) windowThatWasOpened.close();
            var urlWithCode = e.data;

            var idx = urlWithCode.lastIndexOf("code=");
            if(idx === -1) return;
            var code = urlWithCode.substring(idx + 5).replace("#","");

            $http.get("token?code=" + code).then(function(response) {
                var userurl = 'https://www.googleapis.com/plus/v1/people/me?access_token='+response.data.access_token;
                $http.get(userurl).then(function(response) {
                    console.log("user info: "+JSON.stringify(response.data));
                })
            });


        } 
    }]) 

这是我尝试使用以下代码导航到google的代码:

And here is the code I am trying to navigate to google with:

describe('Protractor Demo App', function() {
  it('should have a title', function() {
    browser.get('http://localhost:9000/');

    element(by.id('gLogin')).click().then(function(){
      Google.loginToGoogle();
    });

    expect(browser.getTitle()).toEqual('TrinityIT Time Off Tracking');

     browser.sleep(5000);
  });
});

这是我的conf文件:

And here is my conf file:

exports.config = {
  framework: 'jasmine',
  specs: ['googlePage.js','spec.js'],
  onPrepare: function () {
    global.isAngularSite = function (flag) {
      console.log('Switching to ' + (flag ? 'Asynchronous' : 'Synchronous') + ' mode.')
      browser.ignoreSynchronization = !flag;
    },
      global.BROWSER_WAIT = 5000;
  }
}

推荐答案

假设您要测试的是测试应用程序,而不是测试OAuth对话框,那么有一种更简单的方法.

Assuming that what you're looking to do is test your app, rather than test the OAuth dialogue, then there is an easier approach.

首先是OAuth刷新器,完成所有OAuth任务的全部要点是获得一个访问令牌,该访问令牌可以作为授权:承载xxxxx" HTTP标头包含在您的Google API(例如Drive,YouTube ,日历等)请求.太好了,如果您拥有访问令牌,则可以绕过所有OAuth内容,并且您的应用程序将处于活动状态并且可以进行测试.

First an OAuth refresher, the whole point of doing all the OAuth stuff is that you end up with an Access Token that you can include as an "Authorization: Bearer xxxxx" HTTP Header with your Google API (eg. Drive, YouTube, Calendar, etc) requests. Sooooooo, if you had an Access Token, you could bypass all the OAuth stuff and your app will be active and able to be tested.

因此,您想要的是一种自动方法来获取访问令牌.那很简单.在应用程序代码或量角器前导脚本中的某个位置,您需要获取刷新令牌,并使用该令牌生成可用于您的应用程序的访问令牌.

So, what you want is an automated way to get an Access Token. That's pretty simple. Somewhere, either in your app code or in your Protractor preamble scripts, you need to ingest a Refresh Token, and use that to generate an Access Token which is available to your app.

我使用文件refreshtoken.js来执行此操作,出于安全原因,我小心翼翼地不将其签入git. refreshtoken.js

I do this with a file refreshtoken.js which I carefully do NOT check in to git for security reasons. refreshtoken.js is

var refreshtoken="1x97e978a7a0977...";
var client_id="423432423@gfgfd";

如果您查看

If you look at the answer to How do I authorise an app (web or installed) without user intervention? (canonical ?), you will see the steps to get a Refresh Token, and at the bottom, some JavaScript to show how to use the Refresh Token to fetch an Access Token. It might look like a lot of steps, but you only ever do them once, so it's not too onerous.

这种方法会绕过OAuth,因此如果您要测试的是专门的OAuth,答案就不是答案.但是,它确实允许您以更强大的方式测试您的应用程序.它还具有可用于Karma单元测试以及Protractor e2e测试的优点.

This approach bypasses OAuth, so isn't the answer if it's specifically OAuth that you want to test. However it does allow you to test your app in a much more robust manner. It also has the benefit that it can be used for Karma unit testing as well as Protractor e2e testing.

这篇关于带有量角器的Google身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆