Saya baru mengenal AngularJS, dan saya sedikit bingung bagaimana saya bisa menggunakan angular- "ui-router" dalam skenario berikut:
Saya sedang membangun aplikasi web yang terdiri dari dua bagian. Bagian pertama adalah beranda dengan tampilan masuk dan pendaftarannya, dan bagian kedua adalah dasbor (setelah berhasil masuk).
Saya telah membuat bagian index.html
untuk rumah dengan aplikasi bersudut dan ui-router
konfigurasi untuk menangani /login
dan /signup
melihat, dan ada file lain dashboard.html
untuk bagian dasbor dengan aplikasi danui-router
konfigurasi untuk menangani banyak tampilan sub.
Sekarang saya menyelesaikan bagian dasbor dan tidak tahu bagaimana menggabungkan dua bagian dengan aplikasi sudut yang berbeda. Bagaimana saya bisa memberi tahu aplikasi rumah untuk mengalihkan ke aplikasi dasbor?
sumber
Jawaban:
Saya sedang dalam proses membuat demo yang lebih bagus serta membersihkan beberapa layanan ini menjadi modul yang dapat digunakan, tapi inilah yang saya buat. Ini adalah proses kompleks untuk mengatasi beberapa peringatan, jadi bertahanlah di sana. Anda harus memecah ini menjadi beberapa bagian.
Lihatlah bagian ini .
Pertama, Anda memerlukan layanan untuk menyimpan identitas pengguna. Saya menyebutnya
principal
. Itu dapat diperiksa untuk melihat apakah pengguna login, dan atas permintaan, itu dapat menyelesaikan objek yang mewakili informasi penting tentang identitas pengguna. Ini bisa berupa apa pun yang Anda butuhkan, tetapi yang terpenting adalah nama tampilan, nama pengguna, mungkin email, dan peran yang dimiliki pengguna (jika ini berlaku untuk aplikasi Anda). Kepala sekolah juga memiliki metode untuk melakukan pengecekan peran.Kedua, Anda memerlukan layanan yang memeriksa keadaan yang ingin dituju pengguna, memastikan mereka masuk (jika perlu; tidak perlu untuk masuk, mengatur ulang kata sandi, dll.), Lalu melakukan pengecekan peran (jika aplikasi Anda butuh ini). Jika tidak diautentikasi, kirim ke halaman masuk. Jika mereka diautentikasi, tetapi gagal pemeriksaan peran, kirim mereka ke halaman akses ditolak. Saya memanggil layanan ini
authorization
.Sekarang semua yang perlu Anda lakukan yaitu mendengarkan pada
ui-router
's$stateChangeStart
. Ini memberi Anda kesempatan untuk memeriksa keadaan saat ini, keadaan yang ingin mereka tuju, dan memasukkan cek otorisasi Anda. Jika gagal, Anda dapat membatalkan transisi rute, atau mengubah ke rute lain.Bagian yang sulit tentang melacak identitas pengguna adalah mencarinya jika Anda sudah mengautentikasi (katakanlah, Anda mengunjungi halaman setelah sesi sebelumnya, dan menyimpan token autentikasi dalam cookie, atau mungkin Anda sulit menyegarkan halaman, atau dijatuhkan ke URL dari tautan). Karena cara
ui-router
kerjanya, Anda perlu menyelesaikan identitas Anda satu kali, sebelum pemeriksaan auth. Anda dapat melakukan ini menggunakanresolve
opsi di konfigurasi keadaan Anda. Saya memiliki satu negara induk untuk situs yang mewarisi semua negara bagian, yang memaksa kepala sekolah untuk diselesaikan sebelum hal lain terjadi.Ada masalah lain di sini ...
resolve
hanya dipanggil sekali. Setelah janji Anda untuk pencarian identitas selesai, itu tidak akan menjalankan delegasi ketetapan lagi. Jadi kami harus melakukan pemeriksaan autentikasi Anda di dua tempat: satu kali sesuai dengan janji identitas Anda yang diselesaikan, yang mencakupresolve
pertama kali aplikasi Anda dimuat, dan satu kali lagi$stateChangeStart
jika resolusi telah dilakukan, yang mencakup setiap saat Anda menavigasi ke seluruh negara bagian.OK, jadi apa yang telah kita lakukan sejauh ini?
Kemana kita pergi dari sini? Nah, Anda dapat mengatur negara Anda ke daerah yang membutuhkan tanda. Anda dapat meminta dikonfirmasi / pengguna yang berwenang dengan menambahkan
data
denganroles
ke negara-negara ini (atau orang tua dari mereka, jika Anda ingin menggunakan warisan). Di sini, kami membatasi sumber daya untuk Admin:Sekarang Anda dapat mengontrol negara-oleh-negara apa yang pengguna dapat mengakses rute. Ada masalah lain? Mungkin hanya memvariasikan sebagian dari tampilan berdasarkan apakah mereka masuk atau tidak? Tidak masalah. Gunakan
principal.isAuthenticated()
atau bahkanprincipal.isInRole()
dengan salah satu dari banyak cara Anda dapat menampilkan suatu template atau elemen secara kondisional.Pertama, menyuntikkan
principal
ke controller atau apa pun, dan menempelkannya ke ruang lingkup sehingga Anda dapat menggunakannya dengan mudah dalam pandangan Anda:Tampilkan atau sembunyikan elemen:
Dll, begitu seterusnya, sebagainya. Bagaimanapun, dalam contoh aplikasi Anda, Anda akan memiliki keadaan untuk beranda yang akan membiarkan pengguna yang tidak diauthentikasi mampir. Mereka dapat memiliki tautan ke status masuk atau mendaftar, atau memiliki formulir yang dimasukkan ke dalam halaman itu. Apapun yang cocok untukmu.
Halaman dasbor semua bisa mewarisi dari keadaan yang mengharuskan pengguna untuk masuk dan, katakanlah, menjadi anggota
User
peran. Semua hal otorisasi yang telah kita diskusikan akan mengalir dari sana.sumber
$location.path
alih-alih$state.go
.$scope.user
dithen
fungsi Anda . Anda masih dapat referensiuser
dalam pandangan Anda; ketika itu diselesaikan, tampilan akan diperbarui.$q.when(angular.noop).then(function(){$state.go('myState')
, semuanya berfungsi seperti yang diharapkan. Jika saya menelepon$state.go
saat transisi negara lain tidak selesai, maka itu tidak akan berfungsi (saya pikir itulah alasan mengapa itu tidak akan berhasil).Solusi yang diposting sejauh ini tidak perlu rumit, menurut saya. Ada cara yang lebih sederhana. The dokumentasi
ui-router
mengatakan mendengarkan$locationChangeSuccess
dan penggunaan$urlRouter.sync()
untuk memeriksa transisi negara, menghentikan, atau melanjutkan itu. Tetapi bahkan itu sebenarnya tidak berhasil.Namun, berikut adalah dua alternatif sederhana. Pilih salah satu:
Solusi 1: mendengarkan
$locationChangeSuccess
Anda dapat mendengarkan
$locationChangeSuccess
dan Anda dapat melakukan beberapa logika, bahkan logika asinkron di sana. Berdasarkan logika itu, Anda dapat membiarkan fungsi kembali tidak terdefinisi, yang akan menyebabkan transisi keadaan berlanjut seperti biasa, atau Anda dapat melakukannya$state.go('logInPage')
, jika pengguna perlu diautentikasi. Ini sebuah contoh:Perlu diingat bahwa ini tidak benar-benar mencegah negara target memuat, tetapi itu mengarahkan ulang ke halaman login jika pengguna tidak sah. Tidak apa-apa karena sebenarnya perlindungan ada di server.
Solusi 2: menggunakan status
resolve
Dalam solusi ini, Anda menggunakan
ui-router
fitur tekad .Anda pada dasarnya menolak janji itu
resolve
jika pengguna tidak diautentikasi dan kemudian mengarahkannya ke halaman login.Begini caranya:
Tidak seperti solusi pertama, solusi ini sebenarnya mencegah negara target dari memuat.
sumber
state A
. Mereka mengklik tautan untuk menujuprotected state B
tetapi Anda ingin mengarahkan mereka kembalilogInPage
. Jika tidak ada$timeout
,ui-router
hanya akan menghentikan semua transisi negara, sehingga pengguna akan terjebakstate A
. The$timeout
memungkinkanui-router
untuk pertama mencegah transisi awal untukprotected state B
karena tekad itu ditolak dan setelah itu selesai, itu diarahkan kelogInPage
.authenticate
fungsi sebenarnya disebut?authenticate
Fungsi @Imray diteruskan sebagai parameter untukui-router
. Anda tidak harus menyebutnya sendiri.ui-router
sebut itu.$stateChangeStart
?Solusi termudah adalah dengan menggunakan
$stateChangeStart
danevent.preventDefault()
untuk membatalkan perubahan negara ketika pengguna tidak dikonfirmasi dan mengarahkan dia ke auth negara yang halaman login.sumber
Saya pikir Anda memerlukan
service
yang menangani proses otentikasi (dan penyimpanannya).Dalam layanan ini Anda memerlukan beberapa metode dasar:
isAuthenticated()
login()
logout()
Layanan ini harus disuntikkan di controller Anda masing-masing modul:
service.isAuthenticated()
metode). jika tidak, arahkan ke / loginservice.login()
metodeContoh yang baik dan kuat untuk perilaku ini adalah aplikasi sudut- proyek dan khususnya modul keamanannya yang didasarkan pada Modul Interceptor Auth HTTP yang mengagumkan
Semoga ini membantu
sumber
Saya Membuat modul ini untuk membantu membuat sepotong kue proses ini
Anda dapat melakukan hal-hal seperti:
Atau juga
Ini baru tapi layak untuk dicoba!
https://github.com/Narzerus/angular-permission
sumber
Saya ingin berbagi solusi lain yang bekerja dengan router ui 1.0.0.X
Seperti yang Anda ketahui, stateChangeStart dan stateChangeSuccess sekarang tidak digunakan lagi. https://github.com/angular-ui/ui-router/issues/2655
Sebagai gantinya Anda harus menggunakan $ transisi http://angular-ui.github.io/ui-router/1.0.0-alpha.1/interfaces/transition.ihookregistry.html
Beginilah cara saya mencapainya:
Pertama saya miliki dan AuthService dengan beberapa fungsi yang bermanfaat
Maka saya memiliki konfigurasi ini:
Anda dapat melihat bahwa saya menggunakan
untuk menandai negara hanya dapat diakses jika disahkan.
kemudian, pada .run saya menggunakan transisi untuk memeriksa keadaan diautentikasi
Saya membuat contoh ini menggunakan beberapa kode yang ditemukan pada dokumentasi $ transisi. Saya cukup baru dengan router ui tetapi berfungsi.
Semoga bisa membantu siapa saja.
sumber
Berikut adalah cara kami keluar dari perutean rute tak terbatas dan masih digunakan
$state.go
sebagai ganti$location.path
sumber
Saya punya solusi lain: solusi itu bekerja dengan sempurna ketika Anda hanya memiliki konten yang ingin Anda tampilkan ketika Anda login. Tetapkan aturan di mana Anda memeriksa apakah Anda login dan bukan jalur rute daftar putih.
Dalam contoh saya, saya bertanya apakah saya tidak masuk dan rute saat ini yang saya ingin rute bukan bagian dari `/ login ', karena rute daftar putih saya adalah sebagai berikut
jadi saya punya akses instan ke dua rute ini dan setiap rute lainnya akan diperiksa jika Anda online.
Ini seluruh file perutean saya untuk modul login
() => { /* code */ }
adalah sintaks ES6, gunakan sebagai gantinyafunction() { /* code */ }
sumber
Gunakan $ http Interceptor
Dengan menggunakan interseptor $ http, Anda dapat mengirim header ke Back-end atau sebaliknya dan melakukan pemeriksaan dengan cara itu.
Artikel bagus tentang pencegat $ http
Contoh:
Masukkan ini ke dalam fungsi .config atau .run Anda.
sumber
Pertama, Anda akan memerlukan layanan yang dapat disuntikkan ke pengontrol Anda yang memiliki beberapa gagasan tentang status otentikasi aplikasi. Rincian auth yang ada dengan penyimpanan lokal adalah cara yang layak untuk mendekatinya.
Selanjutnya, Anda harus memeriksa status auth tepat sebelum status berubah. Karena aplikasi Anda memiliki beberapa halaman yang perlu diautentikasi dan yang lain tidak, buat rute induk yang memeriksa auth, dan buat semua halaman lain yang memerlukan yang sama menjadi anak dari orangtua tersebut.
Terakhir, Anda perlu beberapa cara untuk mengetahui apakah pengguna Anda yang saat ini masuk dapat melakukan operasi tertentu. Ini dapat dicapai dengan menambahkan fungsi 'dapat' ke layanan auth Anda. Dapat mengambil dua parameter: - tindakan - wajib - (yaitu 'manage_dashboards' atau 'create_new_dashboard') - objek - opsional - objek sedang dioperasikan. Misalnya, jika Anda memiliki objek dasbor, Anda mungkin ingin memeriksa untuk melihat apakah dashboard.ownerId === loginInUser.id. (Tentu saja, informasi yang dikirimkan dari klien tidak boleh dipercaya dan Anda harus selalu memverifikasi ini di server sebelum menuliskannya ke database Anda).
** PENOLAKAN: Kode di atas adalah kode semu dan tidak disertai jaminan **
sumber