クライアント側とサーバー側の両方で多くの調整をテストした後、次のソリューションを使用することになりました。基本的に、Angular を複数のレイアウトに公開するのをやめて、Rails で処理しました。もちろん、これはユーザーに制限を課します。
アプリは、ダッシュボードと認証の 2 つの主要なセクションに分かれています。したがって、バックエンドでは、ユーザーがログインしている場合は認証ページにアクセスできないように制限し、ユーザーが認証されている場合にのみダッシュボードページにアクセスできるようにします。
問題の根本は、レイアウトを提供する必要がある場合、Rails がどのレイアウトを提供するかを知る方法がなかったことです。Cookie を使用して、認証されたユーザーと認証されていないユーザーを区別しました。Cookie が設定されていて、信頼性テストに合格すると、ダッシュボード レイアウトが読み込まれます。そうしないと、ダッシュボードにアクセスしようとするすべてのユーザーが認証セクションにリダイレクトされます。
class DashboardController < ApplicationController
layout :current_layout
before_filter :authenticate_user
def authenticate_user
if request.xhr? && !cookies[:access_token]
redirect_to "/login"
end
end
def current_layout
if cookies[:access_token]
"dashboard" unless request.xhr?
else
"application" unless request.xhr?
end
end
end
認証セクションについても同様です。
class AuthenticationController < ApplicationController
layout :current_layout
before_filter :redirect_if_authenticated
def redirect_if_authenticated
if request.xhr? && cookies[:access_token]
redirect_to "/dashboard"
end
end
def current_layout
if cookies[:access_token]
"dashboard" unless request.xhr?
else
"application" unless request.xhr?
end
end
end
したがって、ここで注意すべき主な点は次のとおりです。
リクエストが XHR の場合は、レイアウトを再度提供しないでください。レイアウトを再度提供すると、IE9 で無限の読み込みループが発生し、他の IE バージョンでも同様に発生する可能性があります。
サーバー側で URL フラグメントを取得していないため、どのレイアウトをロードする必要があるかを知る方法がありません。そのため、Cookie を信頼できる情報源として使用しており、アクセスはこれのみに基づいて制御されています。
これにより、クライアント側に非対称性が生じます。場合によっては、ユーザーが別のセクションの URL を入力すると、URL とレイアウトがそのまま残ります。サーバーからの URL に基づいて何もできないため、この場合 Cookie は変更されないため、これは Angular で処理する必要があります。
最後のポイントとして、私の場合の認証セクションにはいくつかの可能な URL しかなかったので、次のように正規表現の一致を取得した場合にリダイレクトしました。
if(Modernizr.history) {
if(!/(login|sign|pass)/.test(location.pathname)) {
$location.path('/');
}
} else {
if(location.hash.length > 3 && !/(login|sign|pass)/.test(location.hash)) {
$window.location.href = '/';
}
}
ここで APIをチェックするとhistory
、古い IE ブラウザーでは (他の古いブラウザーでもそうだと思いますが?)、$location.path('/')
一貫してページ全体をリロードしていませんでした。これを使用する場合、$routeProvider
構成は root にリダイレクトする場合に備えて、条件付きでレイアウトもロードする必要があります/
。
$routeProvider
// Code for routes
.otherwise({
// Of course, add something to check access_token authenticity here as well :P
redirectTo: $.cookie('access_token') ? "/dashboard" : "/login"
});
したがって、これらのいくつかの調整により、アプリはすべてのブラウザーで適切に機能し、複数のレイアウトで機能します. もちろん、私は RoR について何も知らないので、誰かが提案するいくつかの改善、またはより良い答えを期待しています。;)