単一ページアプリケーションにおけるログイン状態保持とページアクセス制御の解決策
5524 ワード
単一ページの適用と複数ページの適用
従来のウェブプロジェクトの多くは、ページがジャンプするたびに、バックグラウンドサーバが新しい
html
とそれに関連するcss
とjs
リソース、例えばよく知られているJSP
を返すマルチページアプリケーションである.この応用の最も明らかな欠点は,ページ切替の応答速度が遅いこと,静的リソースの繰返しロードなどである.一方、単一ページアプリケーション(SPA)は、ページジャンプ時に、新しい
html
、css
やjs
などのリソースを要求する必要がなく、多くのhttp
要求を節約し、ページ切り替えの速度を速めることができる.しかし、アプリケーションを最初にロードするときにすべてのページを取得し、最初のスクリーンのロード時間が長くなるという明らかな欠点もあります.幸いなことに、サービス側レンダリング(SSR)技術はこの問題をうまく解決することができる.総合的に見ると,中小規模の応用については,現在では前後端分離を強調する時代に,単ページ応用が好ましい.次の共有は、
vue
、vue-router
およびvuex
を使用して、単一ページアプリケーションを開発する際に発生したいくつかの問題と対応する解決方法です.単一ページで適用されるアクセス権
単一ページアプリケーションは、各ページに1つの
html
ファイルといくつかのcss
ファイルとjs
ファイルを新規作成する必要はありません.ページ切替にはバックエンドの制御は必要ありません.フロントエンドの開発者には友好的に見えるようですが、実際には、多くの単一ページアプリケーションでは、フロントエンドの開発者が考慮しなければならないことが多いようです.主にページアクセス権限の制御にあり、例えばハッシュモードではurlのハッシュ値を手動で変更して異なるルーティングにアクセスすることができるが、実際の応用では、ユーザのこのような操作に対して判断制御が必要であり、例えば、一部のルーティングはログイン後にアクセス権限が必要であり、一部のルーティングに対応するページは特別な権限が必要でアクセスできるなどである.単一ページアプリケーションのページタイプを次の2つに分けます.
ログインページの権限制御
ログインページの特殊な点は、ログインページは、ユーザがログイン操作を行う必要がある場合にのみ表示されるべきであり、すなわち、ユーザのログイン状態が期限切れでなければ、ユーザはログインページのルーティングにアクセスできないことである.
ログイン後にアクセスできるページの権限制御
vue
アプリケーションでは、通常、mounted
メソッドでajax
要求取得データが送信される.しかし、単一ページアプリケーションではurlのハッシュ値を変更して異なるルーティングにアクセスすることができるが、パーソナルセンターなどの一部のページでは、有効なデータを表示するには、ユーザーがログインしてから有効なデータを取得する必要がある.ユーザがこのルーティングのページにアクセスできるようにする簡単な処理方法があるが、ajax
は有効なデータを取得できないが、明らかに最善の解決策ではない.好ましい方法は、vue-router
のライフサイクル関数によって、これらのルーティングに入る前に、ユーザがログインしているかどうかを判断し、ログインしていない場合はログインページのルーティングにリダイレクトすることである.router.beforeEach((to, from, next) => {
if (to.path == '/login') { //
if (login) { // ,
next('/');
} else { //
next();
}
} else { //
if (login) { // ,
next();
} else { // ,
next('/login');
}
}
})
ログインステータス
以上の解析により,問題は最終的にフロントエンドがユーザのログイン状態をどのように判断するかを指す.
通常、フロントエンドは要求の送信のみを担当し、応答表示ページによって異なる内容が表示され、その後、
sessionId
またはtoken
によってユーザのログイン状態が期限切れであるか否かが判断される.では、フロントエンドでは、ユーザーのログイン状態が有効かどうかを記録(保存)する方法はありますか?クライアントストレージ
sessionStorage
、localStorage
、cookie
は、フロントエンドでよく使用されるクライアント記憶方法である.cookie
バックエンドに記憶能力を持たせる解決策としては、通常、
sessionId
/token
のようなバックエンド判定要求が誰に来たのかを判断する情報が携帯され、前述したように、これらの情報はバックエンドによって期限切れか否かが判断され、一般的にはcookie
にログイン状態が有効か否かを直接記憶することはない.sessionStorage
ブラウザに格納すると、ユーザ登録に成功した後に
setItem
で属性を保存し、ルーティングのライフサイクル関数beforeEach
でgetItem
で登録済みか否かを判断することができる.実装は簡単ですが、多くの問題があります.sessionStorage
自体の有効期限は、ユーザのログイン状態がsessionStorage
の有効期限と同期することを決定する.たとえば、バックエンドにcookie
のexpire
プロパティが設定されているかどうかにかかわらず、ブラウザを閉じた後に再ログインする必要があります.sessionStorage
はまだ有効であり、ユーザーが本能的にページにアクセスできるようになったが、データがないだけだ.ユーザーは、いくつかの操作でsessionStorage
を無効にすることができます(ブラウザウィンドウを閉じて再読み込み)sessionStorage
がなくなり、ユーザーが再ログインする必要があります.sessionStorage
は読み書き可能であり、ブラウザのデバッグツールではclear
などの方法を簡単に実行でき、setItem
の値を簡単に読み取ることができ、セキュリティが低いことによってsessionStorage
は重要な情報を格納できないことが決定される.localStorage
有効期限が
sessionStorage
と異なる場合を除き、他の機能は類似しています.ストレージの適用
アプリケーションに格納されるのは、通常、
vuex
にユーザがログインしているかどうかを記録することである.ルーティングのライフサイクル関数beforeEach
でこのデータを読み出し、ユーザのログイン状態が有効か否かを判断する.では、質問が来ました.私の解決策は、ログインステータスが有効かどうかを判断するリクエストを送信することです.データの取得要求に対して、戻り値の情報が再ログインを必要とする場合、
vuex
をクリアし、ログインページにリダイレクトする.vuex
を利用してログイン状態を記録する際に発生するすべての状況と処理方法を見てみましょう.router.beforeEach(async (to, from, next) => {
if (to.path == '/login') { //
if (store.login) {
// ,
// url hash
next('/');
} else {
// ajax
const login = await ajax();
if (login) {
// store,
store.commit('login', true);
next('/');
} else {
next();
}
}
} else { //
if (store.login) {
// ,
next();
} else {
// , url hash
// ajax
const login = await ajax();
if (login) {
// store,
store.commit('login', true);
next();
} else {
next('/login');
}
}
}
})
また、各取得データの要求に対して、バックエンドの戻り値においてユーザのログイン状態が期限切れである場合、
vuex
のログイン状態を変更してログインページにリダイレクトする.store.commit('login', false);
location.href = '/#/login';
location.reload();