我這篇文章AngularJS和ASP.Net的WebAPI(這是相當不錯的)社會登錄以下:AngularJS和ASP.Net的WebAPI社會登錄移動瀏覽器上
ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app
漂亮的多,在通過桌面瀏覽器(例如Chrome,FF,IE,Edge)運行社交登錄時,代碼可以正常工作。社交登錄會在新窗口中打開(不是選項卡),您可以使用Google或Facebook帳戶,並且一旦通過其中的任何一個登錄,就會重定向到回調頁面(authComplete.html),而回調頁面定義了一個JS文件(authComplete.js),可以關閉窗口並在父窗口上執行命令。
的angularJS控制器,它調用外部登錄網址和桌面瀏覽器打開一個彈出窗口(不是標籤):
loginController.js
'use strict';
app.controller('loginController', ['$scope', '$location', 'authService', 'ngAuthSettings', function ($scope, $location, authService, ngAuthSettings) {
$scope.loginData = {
userName: "",
password: "",
useRefreshTokens: false
};
$scope.message = "";
$scope.login = function() {
authService.login($scope.loginData).then(function (response) {
$location.path('/orders');
},
function (err) {
$scope.message = err.error_description;
});
};
$scope.authExternalProvider = function (provider) {
var redirectUri = location.protocol + '//' + location.host + '/authcomplete.html';
var externalProviderUrl = ngAuthSettings.apiServiceBaseUri + "api/Account/ExternalLogin?provider=" + provider
+ "&response_type=token&client_id=" + ngAuthSettings.clientId
+ "&redirect_uri=" + redirectUri;
window.$windowScope = $scope;
var oauthWindow = window.open(externalProviderUrl, "Authenticate Account", "location=0,status=0,width=600,height=750");
};
$scope.authCompletedCB = function (fragment) {
$scope.$apply(function() {
if (fragment.haslocalaccount == 'False') {
authService.logOut();
authService.externalAuthData = {
provider: fragment.provider,
userName: fragment.external_user_name,
externalAccessToken: fragment.external_access_token
};
$location.path('/associate');
}
else {
//Obtain access token and redirect to orders
var externalData = { provider: fragment.provider, externalAccessToken: fragment.external_access_token };
authService.obtainAccessToken(externalData).then(function (response) {
$location.path('/orders');
},
function (err) {
$scope.message = err.error_description;
});
}
});
}
}]);
authComplete.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<script src="scripts/authComplete.js"></script>
</body>
</html>
authComplete.js
window.common = (function() {
var common = {};
common.getFragment = function getFragment() {
if (window.location.hash.indexOf("#") === 0) {
return parseQueryString(window.location.hash.substr(1));
} else {
return {};
}
};
function parseQueryString(queryString) {
var data = {},
pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;
if (queryString === null) {
return data;
}
pairs = queryString.split("&");
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i];
separatorIndex = pair.indexOf("=");
if (separatorIndex === -1) {
escapedKey = pair;
escapedValue = null;
} else {
escapedKey = pair.substr(0, separatorIndex);
escapedValue = pair.substr(separatorIndex + 1);
}
key = decodeURIComponent(escapedKey);
value = decodeURIComponent(escapedValue);
data[key] = value;
}
return data;
}
return common;
})();
var fragment = common.getFragment();
window.location.hash = fragment.state || '';
window.opener.$windowScope.authCompletedCB(fragment);
window.close();
我遇到的問題是,當我運行在移動設備(Safari瀏覽器,Chrome瀏覽器手機)上的應用,社交登錄窗口中的一個新的標籤和其目的是通過JS函數打開返回片段到主應用程序窗口不執行並且新選項卡不關閉。
實際上,你可以通過應用程序嘗試了桌面和移動瀏覽器的這種行爲:
http://ngauthenticationapi.azurewebsites.net/
我已經在這方面到目前爲止已經試過在登錄控制器,我修改了功能,所以該外部登錄網址在同一窗口內打開:
$scope.authExternalProvider = function (provider) {
var redirectUri = location.protocol + '//' + location.host + '/authcomplete.html';
var externalProviderUrl = ngAuthSettings.apiServiceBaseUri + "api/Account/ExternalLogin?provider=" + provider
+ "&response_type=token&client_id=" + ngAuthSettings.clientId
+ "&redirect_uri=" + redirectUri;
window.location = externalProviderUrl;
};
並修改了authComplete.js common.getFragment函數返回到登錄頁面,通過附加由社會提供的訪問令牌登錄,查詢字符串:
common.getFragment = function getFragment() {
if (window.location.hash.indexOf("#") === 0) {
var hash = window.location.hash.substr(1);
var redirectUrl = location.protocol + '//' + location.host + '/#/login?ext=' + hash;
window.location = redirectUrl;
} else {
return {};
}
};
而在登錄控制器,我添加了一個函數來解析查詢字符串,並嘗試調用像$ scope.authCompletedCB(片段)功能:
var vm = this;
var fragment = null;
vm.testFn = function (fragment) {
$scope.$apply(function() {
if (fragment.haslocalaccount == 'False') {
authenticationService.logOut();
authenticationService.externalAuthData = {
provider: fragment.provider,
userName: fragment.external_user_name,
externalAccessToken: fragment.external_access_token
};
$location.path('/associate');
}
else {
//Obtain access token and redirect to orders
var externalData = { provider: fragment.provider, externalAccessToken: fragment.external_access_token };
authenticationService.obtainAccessToken(externalData).then(function (response) {
$location.path('/home');
},
function (err) {
$scope.message = err.error_description;
});
}
});
}
init();
function parseQueryString(queryString) {
var data = {},
pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;
if (queryString === null) {
return data;
}
pairs = queryString.split("&");
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i];
separatorIndex = pair.indexOf("=");
if (separatorIndex === -1) {
escapedKey = pair;
escapedValue = null;
} else {
escapedKey = pair.substr(0, separatorIndex);
escapedValue = pair.substr(separatorIndex + 1);
}
key = decodeURIComponent(escapedKey);
value = decodeURIComponent(escapedValue);
data[key] = value;
}
return data;
}
function init() {
var idx = window.location.hash.indexOf("ext=");
if (window.location.hash.indexOf("#") === 0) {
fragment = parseQueryString(window.location.hash.substr(idx));
vm.testFn(fragment);
}
}
但很明顯這是給我相關的角度(這是我目前所面對的任何線索)的錯誤:
https://docs.angularjs.org/error/$rootScope/inprog?p0=$digest
所以,幾乎是它是我的一個死衚衕在這個階段。
任何想法或意見將不勝感激。
Gracias!
更新:我設法解決有關被引發的rootcope的角度錯誤,但可悲的是,解決這並不能解決主要問題。如果我試圖在我的應用程序的相同瀏覽器選項卡上打開社交登錄,Google可以登錄並返回到應用程序並傳遞所需的令牌。對於Facebook來說,這是一個不同的故事,在開發者工具控制檯中,有一個警告似乎阻止Facebook顯示登錄頁面。
非常多,打開一個新窗口(或標籤)的原始方法是前進的方向,但修復移動瀏覽器的方法似乎越來越具有挑戰性。
我會花時間在當天晚些時候測試了這一點。 – Batuta
你不需要,'localStorage'是瀏覽器中的HTML5 API的一部分,實際上它在'window'上,你可以在任何地方使用'window.localStorage'來訪問它。 – udidu
剛剛試過這個,現在我我得到了一些rootcope錯誤錯誤:$ rootScope:inprog 操作已在進行中 – Batuta