ページの読み込み時にcurrentUser()
によってサーバーを1回だけ呼び出す、グローバルにアクセス可能な独自のサービスを作成するには、ユーザーがログインしている場合はそれを保持し、ログアウトするまでデータをコントローラーまたは状態に提供しますか?今、私は多くの状態またはコントローラーで何度も解決していますcurrentUser()
、ドキュメントで見つけました: authparseresponse 独自のサービスを作成する可能性がありますが、方法がわかりませんこれを正しい方法で処理します。
たとえば、ui-routerでは2つのサーバー呼び出しがあり、ページが読み込まれた場合にのみ十分です。
.state('login', {
url: '/login',
templateUrl: 'auth/_login.html',
controller: 'AuthCtrl',
onEnter: [
'$state', 'Auth',
function($state, Auth) {
Auth.currentUser().then(function() {
$state.go('home');
});
}
]
})
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
onEnter: [
'$state', 'Auth',
function($state, Auth) {
Auth.currentUser().then(function(user) {}, function(err) {
$state.go('home');// user not logged in
});
}
]
})
または、次のサーバーがNavControllerを呼び出すたびに:
app.controller('NavController', [
'$state', '$scope', 'Auth', function($state, $scope, Auth) {
$scope.signedIn = Auth.isAuthenticated;
$scope.logout = Auth.logout; // logout function
Auth.currentUser().then(function(user) {
$scope.user = user;
});
$scope.$on('devise:login', function(e, user) {
$scope.user = user;
});
$scope.$on('devise:logout', function(e, user) {
$scope.user = {};
$state.go("home");
});
}
]);
私は答えのない同様の質問を見つけました: stackoverflow
ご存知のとおり、ファクトリはシングルトンオブジェクトであり、基本的にはデータ共有に使用されます。任意のコントローラーに注入でき、依存関係として機能します。これで問題が解決する場合もあります。このサービスを状態解決ブロックに挿入し、ユーザーが存在するかどうかを確認してから、ファクトリのユーザーフェッチ関数を呼び出します。
app.factory("User", function($http, $q, $rootScope) {
var user = null;
return {
fetchUser: function() {
/*your ajax call that return current user*/
user = YOUR_SERVER_RESPONSE;
return user;
},
getUser : function(){
return user;
},
setUser : function(u){
user = u;
}
}
});
状態構成ブロックは次のようになります
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
resolve : function(User){
if(User.getUser()){
return User.getUser();
}else{
return User.fetchUser();
}
}
})
大規模なAngularアプリでユーザー認証を処理する必要があり、この記事は非常に便利であることがわかりました: https://medium.com/opinionated-angularjs/techniques-for- authentication-in-angularjs-applications-7bbf0346acec
「それを一度だけ実現する方法」に固有:
resolve
要件として追加します(ネストされた状態を使用する場合)ユーザーのログイン状態を表すUserService
サービスは、アプリケーション全体で状態を共有するのに適しています。ログインおよびログアウト機能は、このサービスを通じて公開でき、ユーザーの詳細もここに保存できます。 $resource
を拡張するUserApi
を定義することは、実際のHTTPの懸念をユーザー状態の管理から分離するのにも役立つでしょう。
記事で取り上げられているその他の懸念事項:ページの更新後の永続的な状態、およびユーザーがログインしている場合にのみアクセスできるサイトの領域。
メインのHTMLページの下部に次のJavaScript(jQuery)コードを追加することで、current_user情報の問題をangular)で解決しました。
$("meta[name=current_user]").data('current_user', {
id: <%=j current_user.id.to_s %>,
username: "<%=j current_user.full_name.to_s %>"
});
必要な情報を解析できます。これはたまたまRails Projectであり、必要なのはIDとNAMEだけでした(IDを使用してUserファクトリオブジェクトをクエリし、JSONを受け取ることができます)必要に応じて完全な情報)。
次に、AngularJS Controllerに追加できます(mine iscoffeescript):
# Grab User Info
current_user = angular.element("meta[name=current_user]").data 'current_user'
# Stop Here if you Have the Info you Need
$scope.user = current_user
# **** OR Get More Info if User is Logged In
if current_user.id is not undefined
$scope.user = User.get {id: current_user.id}
これが私のファクトリコードユーザー向けです(coffeescriptagain):
# In order to prevent minification from effecting the code
# must wrap functions as arrays and pass in the variables as
# strings before the function call
app.factory "User", ["$resource", ($resource) ->
$resource("/api/angular/users/:id",
{ id: "@id" },
{
update: { method: "PUT" }
})
]
ご不明な点がございましたらお知らせください。
編集:angular_deviceモジュールで使用するためにいくつかのパーツを変更する
一般的に、私はここで提供されるソリューションを使用しています( https://vickev.com/#!/article/authentication-in-single-page-applications-node-js-passportjs-angularjs ) HTTP呼び出しごとにユーザーがログインしているかどうかを確認する方法について説明します。
ユーザーがログインしている場合は、ロードを確認します
myApp.config(['$routeProvider','$locationProvider',
function($routeProvider, $locationProvider) {
//================================================
// Check if the user is connected
//================================================
var checkLoggedin = function($q, $rootScope, Auth, User){
// Initialize a new promise
var deferred = $q.defer();
Auth.currentUser().then(function(userObj){
deferred.resolve();
//option a: just save the user object into the $rootScope
$rootScope.User = userObj;
//option b: create a factory 'User' and a method 'save()' which parses the JSON returned from your Server
User.save(userObj);
}, function(error){
deferred.reject();
});
return deferred.promise;
};
//================================================
// Define all the routes
//================================================
$routeProvider
//Start page, where the user gets a list of registered SO and can add new ones
.when('/', {
templateUrl: 'templates/index.html',
controller: 'indexCtrl',
resolve: {
loggedin: checkLoggedin
}
})
.when('/login', {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
})
// do more here
.otherwise({
redirectTo: '/'
});
}]).run(function($rootScope, $http){
//Do some initial tasks or set some values
});
「User」という名前の追加のサービスを作成し(サービスはシングルトンであるため)、いくつかのメソッドを定義します。 save()およびget()は、ユーザーをサービスシングルトンに保存し、必要な場所に返すようにします。関数「checkLoggedIn」を使用すると、ルートの「解決」オプションを定義でき、promiseが解決された場合、ユーザーは制限されたページにアクセスできます。
ユーザーの詳細をGlobal.userに保存します。コントローラーまたはサービスで「グローバル」モジュールを使用します。
ユーザーにアクセスする必要がある場合は、Global.userを使用してアクセスします。