Saya berasal dari dunia MVC Asp.Net di mana pengguna mencoba mengakses halaman yang tidak mereka otorisasi secara otomatis diarahkan ke halaman login.
Saya mencoba mereproduksi perilaku ini di Angular. Saya menemukan dekorator @CanActivate, tetapi menghasilkan komponen yang tidak merender sama sekali, tidak ada pengalihan.
Pertanyaan saya adalah sebagai berikut:
- Apakah Angular menyediakan cara untuk mencapai perilaku ini?
- Jika ya, bagaimana caranya? Apakah ini praktik yang baik?
- Jika tidak, apa praktik terbaik untuk menangani otorisasi pengguna di Angular?
login
typescript
angular
angular2-routing
Amaury
sumber
sumber
Jawaban:
Pembaruan: Saya telah menerbitkan proyek kerangka penuh Angular 2 dengan integrasi OAuth2 di Github yang menunjukkan arahan yang disebutkan di bawah ini dalam tindakan.
Salah satu cara untuk melakukannya adalah melalui penggunaan a
directive
. Tidak seperti Angular 2components
, yang pada dasarnya adalah tag HTML baru (dengan kode terkait) yang Anda sisipkan ke halaman Anda, direktif atributif adalah atribut yang Anda masukkan ke dalam tag yang menyebabkan beberapa perilaku terjadi. Dokumen di sini .Kehadiran atribut khusus Anda menyebabkan hal-hal terjadi pada komponen (atau elemen HTML) yang Anda tempatkan arahannya. Pertimbangkan arahan yang saya gunakan untuk aplikasi Angular2 / OAuth2 saya saat ini:
Ini memanfaatkan layanan Otentikasi yang saya tulis untuk menentukan apakah pengguna sudah masuk atau tidak dan juga berlangganan ke acara otentikasi sehingga dapat menendang pengguna keluar jika dia logout atau waktu keluar.
Anda bisa melakukan hal yang sama. Anda akan membuat arahan seperti milik saya yang memeriksa keberadaan cookie yang diperlukan atau informasi status lainnya yang menunjukkan bahwa pengguna diautentikasi. Jika mereka tidak memiliki flag yang Anda cari, arahkan pengguna ke halaman publik utama Anda (seperti yang saya lakukan) atau server OAuth2 Anda (atau apa pun). Anda akan meletakkan atribut direktif itu pada setiap komponen yang perlu dilindungi. Dalam hal ini, mungkin disebut
protected
seperti dalam petunjuk yang saya tempel di atas.Kemudian Anda ingin menavigasi / mengarahkan pengguna ke tampilan login dalam aplikasi Anda, dan menangani otentikasi di sana. Anda harus mengubah rute saat ini ke yang Anda inginkan. Jadi dalam hal ini Anda akan menggunakan injeksi ketergantungan untuk mendapatkan objek Router dalam
constructor()
fungsi direktif Anda dan kemudian menggunakannavigate()
metode untuk mengirim pengguna ke halaman login Anda (seperti dalam contoh saya di atas).Ini mengasumsikan bahwa Anda memiliki serangkaian rute di suatu tempat yang mengontrol
<router-outlet>
tag yang terlihat seperti ini, mungkin:Jika, sebaliknya, Anda perlu mengarahkan pengguna ke URL eksternal , seperti server OAuth2 Anda, maka Anda akan meminta arahan Anda melakukan sesuatu seperti berikut:
sumber
Berikut adalah contoh yang diperbarui menggunakan Angular 4 (juga kompatibel dengan Angular 5 - 8)
Rute dengan rute asal dilindungi oleh AuthGuard
AuthGuard mengalihkan ke halaman login jika pengguna tidak login
Diperbarui untuk meneruskan url asli dalam parameter kueri ke halaman login
Untuk contoh lengkap dan demo kerja Anda dapat melihat posting ini
sumber
currentUser
di dalamlocalStorage
masih dapat mengakses rute yang dilindungi? misalnya.localStorage.setItem('currentUser', 'dddddd')
?Penggunaan dengan router terakhir
Dengan diperkenalkannya router baru, menjadi lebih mudah untuk menjaga rute. Anda harus menentukan penjaga, yang bertindak sebagai layanan, dan menambahkannya ke rute.
Sekarang teruskan
LoggedInGuard
ke rute dan tambahkan juga keproviders
larik modul.Deklarasi modul:
Posting blog mendetail tentang cara kerjanya dengan rilis final: https://medium.com/@blacksonic86/angular-2-authentication-revisited-611bf7373bf9
Penggunaan dengan router yang tidak digunakan lagi
Solusi yang lebih kuat adalah memperpanjang
RouterOutlet
dan saat mengaktifkan rute, periksa apakah pengguna login. Dengan cara ini Anda tidak perlu menyalin dan menempelkan perintah Anda ke setiap komponen. Selain itu, pengalihan berdasarkan subkomponen bisa menyesatkan.The
UserService
singkatan tempat di mana logika bisnis Anda berada apakah pengguna masuk log atau tidak. Anda dapat menambahkannya dengan mudah dengan DI di konstruktor.Saat pengguna menavigasi ke url baru di situs web Anda, metode pengaktifan dipanggil dengan Instruksi saat ini. Dari situ Anda dapat mengambil url dan memutuskan apakah diizinkan atau tidak. Jika tidak langsung saja ke halaman login.
Satu hal terakhir yang tersisa untuk membuatnya berfungsi, adalah meneruskannya ke komponen utama kami, bukan ke komponen bawaan.
Solusi ini tidak dapat digunakan dengan
@CanActive
dekorator siklus hidup, karena jika fungsi yang diteruskan kepadanya menyelesaikan kesalahan, metode pengaktifanRouterOutlet
tidak akan dipanggil.Juga menulis posting blog rinci tentang itu: https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492
sumber
Failed to lint <classname>.router-outlet.ts[15,28]. In the constructor of class "LoggedInRouterOutlet", the parameter "nameAttr" uses the @Attribute decorator, which is considered as a bad practice. Please, consider construction of type "@Input() nameAttr: string".
Tidak dapat menemukan apa yang harus diubah di konstruktor ("_parentRounter") untuk menyingkirkan pesan ini. Ada pemikiran?_parentRouter: Router, @Input() nameAttr: string,
dan tslint tidak lagi menimbulkan kesalahan. Juga menggantikan impor "Atribut" menjadi "Input" dari inti sudut. Semoga ini membantu.Tolong, jangan menimpa Outlet Router! Ini mimpi buruk dengan rilis router terbaru (3.0 beta).
Sebagai gantinya gunakan antarmuka CanActivate dan CanDeactivate dan setel kelas sebagai canActivate / canDeactivate dalam definisi rute Anda.
Seperti itu:
Kelas:
Lihat juga: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
sumber
Mengikuti jawaban luar biasa di atas, saya juga ingin
CanActivateChild
: menjaga rute anak. Dapat digunakan untuk menambahkanguard
ke rute turunan yang berguna untuk kasus seperti ACLIni berjalan seperti ini
Ini diambil dari https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
sumber
Lihat kode ini, file auth.ts
sumber
1. Create a guard as seen below. 2. Install ngx-cookie-service to get cookies returned by external SSO. 3. Create ssoPath in environment.ts (SSO Login redirection). 4. Get the state.url and use encodeURIComponent.
sumber