Mengintegrasikan Login Facebook di Aplikasi AngularJS dengan Satellizer

Diterbitkan: 2022-03-11

Dengan kedatangan kerangka kerja front-end yang kaya fitur seperti AngularJS, semakin banyak logika yang diterapkan di front-end, seperti manipulasi/validasi data, otentikasi, dan banyak lagi. Satellizer, modul otentikasi berbasis token yang mudah digunakan untuk AngularJS, menyederhanakan proses penerapan mekanisme otentikasi di AngularJS, Pustaka dilengkapi dengan dukungan bawaan untuk Google, Facebook, LinkedIn, Twitter, Instagram, GitHub, Bitbucket, Yahoo, Twitch , dan akun Microsoft (Windows Live).

Pada artikel ini, kami akan membangun aplikasi web yang sangat sederhana mirip dengan yang ada di sini yang memungkinkan Anda untuk masuk dan melihat informasi pengguna saat ini.

Otentikasi vs Otorisasi

Ini adalah 2 kata menakutkan yang sering Anda temui setelah aplikasi Anda mulai mengintegrasikan sistem pengguna. Menurut Wikipedia:

Otentikasi adalah tindakan mengkonfirmasi kebenaran atribut dari satu bagian data (datum) yang diklaim benar oleh suatu entitas.

Otorisasi adalah fungsi menentukan hak akses ke sumber daya yang terkait dengan keamanan informasi dan keamanan komputer secara umum dan untuk kontrol akses pada khususnya.

Dalam istilah awam, mari kita ambil contoh situs blog dengan beberapa orang yang mengerjakannya. Para blogger menulis artikel dan pengelola memvalidasi konten. Setiap orang dapat mengotentikasi (login) ke dalam sistem tetapi hak (otorisasi) mereka berbeda, sehingga blogger tidak dapat memvalidasi konten sedangkan pengelola dapat.

Mengapa Satelizer?

Anda dapat membuat sistem otentikasi Anda sendiri di AngularJS dengan mengikuti beberapa tutorial seperti yang sangat rinci ini: Tutorial Token Web JSON: Contoh di Laravel dan AngularJS. Saya sarankan membaca artikel ini karena menjelaskan JWT (JSON Web Token) dengan sangat baik, dan menunjukkan cara sederhana untuk mengimplementasikan otentikasi di AngularJS menggunakan penyimpanan lokal dan pencegat HTTP secara langsung.

Jadi mengapa Satelizer? Alasan utamanya adalah mendukung beberapa login jejaring sosial seperti Facebook, Twitter, dll. Saat ini, terutama untuk situs web yang digunakan di seluler, mengetik nama pengguna dan kata sandi cukup rumit dan pengguna berharap dapat menggunakan situs web Anda dengan sedikit hambatan dengan menggunakan login sosial. Karena mengintegrasikan SDK dari setiap jejaring sosial dan mengikuti dokumentasinya cukup berulang, alangkah baiknya untuk mendukung login sosial ini dengan sedikit usaha.

Apalagi Satellizer adalah proyek aktif di Github. Aktif adalah kuncinya di sini karena SDK ini cukup sering berubah dan Anda tidak ingin membaca dokumentasinya sesekali (siapa pun yang bekerja dengan SDK Facebook tahu betapa menjengkelkannya itu)

Aplikasi AngularJS dengan Login Facebook

Di sinilah hal-hal mulai menjadi menarik.

Kami akan membangun aplikasi web yang memiliki mekanisme login/registrasi reguler (yaitu menggunakan nama pengguna, kata sandi) dan juga mendukung login sosial. Aplikasi web ini sangat sederhana karena hanya memiliki 3 halaman:

  • Halaman beranda: siapa pun dapat melihat
  • Halaman login: untuk memasukkan username/password
  • Halaman rahasia: yang hanya dapat dilihat oleh pengguna yang masuk

Untuk backend, kita akan menggunakan Python dan Flask. Python dan kerangka kerja Flask cukup ekspresif jadi saya harap mem-porting kode ke bahasa/kerangka kerja lain tidak akan terlalu sulit. Kami tentu saja akan menggunakan AngularJS untuk front-end. Dan untuk login sosial, kami hanya akan berintegrasi dengan Facebook karena ini adalah jejaring sosial paling populer saat ini.

Ayo mulai!

Langkah #1: Proyek Bootstrap

Berikut adalah bagaimana kita akan menyusun kode kita:

 - app.py - static/ - index.html - app.js - bower.json - partials/ - login.tpl.html - home.tpl.html - secret.tpl.html

Semua kode back-end ada di app.py . Kode front-end diletakkan di folder static/. Secara default, Flask akan secara otomatis menyajikan isi folder static/. Semua tampilan parsial berada di static/partials/ dan ditangani oleh modul ui.router.

Untuk memulai pengkodean back-end, kita memerlukan Python 2.7.* dan menginstal pustaka yang diperlukan menggunakan pip. Anda tentu saja dapat menggunakan virtualenv untuk mengisolasi lingkungan Python. Di bawah ini adalah daftar modul Python yang diperlukan untuk dimasukkan ke dalam requirements.txt:

 Flask==0.10.1 PyJWT==1.4.0 Flask-SQLAlchemy==1.0 requests==2.7.0

Untuk menginstal semua dependensi ini:

 pip install -r requirements.txt

Di app.py kami memiliki beberapa kode awal untuk bootstrap Flask (pernyataan impor dihilangkan untuk singkatnya):

 app = Flask(__name__) @app.route('/') def index(): return flask.redirect('/static/index.html') if __name__ == '__main__': app.run(debug=True)

Selanjutnya kita init bower dan menginstal AngularJS dan ui.router:

 bower init # here you will need to answer some question. when in doubt, just hit enter :) bower install angular angular-ui-router --save # install and save these dependencies into bower.json

Setelah pustaka ini diinstal, kita perlu memasukkan AngularJS dan ui-router di index.html dan membuat perutean untuk 3 halaman: beranda, masuk, dan rahasia.

 <body ng-app="DemoApp"> <a ui-sref="home">Home</a> <a ui-sref="login">Login</a> <a ui-sref="secret">Secret</a> <div ui-view></div> <script src="bower_components/angular/angular.min.js"></script> <script src="bower_components/angular-ui-router/release/angular-ui-router.min.js"></script> <script src="main.js"></script> </body>

Di bawah ini adalah kode yang kita butuhkan di main.js untuk mengkonfigurasi perutean:

 var app = angular.module('DemoApp', ['ui.router']); app.config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('home', { url: '/home', templateUrl: 'partials/home.tpl.html' }) .state('secret', { url: '/secret', templateUrl: 'partials/secret.tpl.html', }) .state('login', { url: '/login', templateUrl: 'partials/login.tpl.html' }); $urlRouterProvider.otherwise('/home'); });

Pada titik ini jika Anda menjalankan server python app.py , Anda harus memiliki antarmuka dasar ini di http://localhost:5000

Antarmuka masuk dasar

Tautan Beranda, Masuk, dan Rahasia harus berfungsi pada saat ini dan menunjukkan konten templat yang sesuai.

Selamat, Anda baru saja selesai menyiapkan kerangka! Jika Anda menemukan kesalahan, silakan periksa kode di GitHub

Langkah #2: Masuk dan Daftar

Di akhir langkah ini, Anda akan memiliki aplikasi web yang dapat Anda daftarkan/login menggunakan email dan kata sandi.

Langkah pertama adalah mengkonfigurasi backend. Kami membutuhkan model Pengguna dan cara untuk menghasilkan token JWT untuk pengguna tertentu. Model Pengguna yang ditunjukkan di bawah ini benar-benar disederhanakan dan bahkan tidak melakukan pemeriksaan dasar apa pun seperti jika email bidang berisi "@", atau jika kata sandi bidang berisi setidaknya 6 karakter, dll.

 class User(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(100), nullable=False) password = db.Column(db.String(100)) def token(self): payload = { 'sub': self.id, 'iat': datetime.utcnow(), 'exp': datetime.utcnow() + timedelta(days=14) } token = jwt.encode(payload, app.config['TOKEN_SECRET']) return token.decode('unicode_escape')

Kami menggunakan modul jwt di python untuk menghasilkan bagian payload di JWT. Bagian iat dan exp sesuai dengan stempel waktu token dibuat dan kedaluwarsa. Dalam kode ini, token akan kedaluwarsa dalam 2 minggu.

Setelah model User dibuat, kita dapat menambahkan endpoint “login” dan “register”. Kode untuk keduanya sangat mirip, jadi di sini saya hanya akan menunjukkan bagian "daftar". Harap dicatat bahwa secara default, Satellizer akan memanggil titik akhir /auth/login dan /auth/signup masing-masing untuk "login" dan "register".

 @app.route('/auth/signup', methods=['POST']) def signup(): data = request.json email = data["email"] password = data["password"] user = User(email=email, password=password) db.session.add(user) db.session.commit() return jsonify(token=user.token())

Mari kita periksa titik akhir menggunakan curl terlebih dahulu:

 curl localhost:5000/auth/signup -H "Content-Type: application/json" -X POST -d '{"email":"[email protected]","password":"xyz"}'

Hasilnya akan terlihat seperti ini:

 { "token": "very long string…." }

Sekarang bagian back-end sudah siap, mari kita serang front-end! Pertama, kita perlu menginstal satellizer dan menambahkannya sebagai dependensi di main.js:

 bower install satellizer --save

Tambahkan satellizer sebagai ketergantungan:

 var app = angular.module('DemoApp', ['ui.router', 'satellizer']);

Masuk dan mendaftar di satellizer sebenarnya cukup sederhana dibandingkan dengan semua pengaturan sampai sekarang:

 $scope.signUp = function () { $auth .signup({email: $scope.email, password: $scope.password}) .then(function (response) { // set the token received from server $auth.setToken(response); // go to secret page $state.go('secret'); }) .catch(function (response) { console.log("error response", response); }) };

Jika Anda mengalami kesulitan dalam menyiapkan kode, Anda dapat melihat kode di GitHub.

Langkah #3: Tapi Tampilan Rahasia Tidak Benar-Benar Rahasia, Karena Siapapun Bisa Melihatnya!

Ya itu benar! Hingga saat ini, siapa pun dapat membuka halaman rahasia tanpa harus login.

Saatnya menambahkan beberapa pencegat di AngularJS untuk memastikan bahwa jika seseorang pergi ke halaman rahasia dan jika pengguna ini tidak masuk, mereka akan diarahkan ke halaman masuk.

Pertama, kita harus menambahkan sebuah flag yang dibutuhkanLogin untuk membedakan halaman rahasia dari yang lain.

 .state('secret', { url: '/secret', templateUrl: 'partials/secret.tpl.html', controller: 'SecretCtrl', data: {requiredLogin: true} })

Bagian "data" akan digunakan dalam acara $stateChangeStart yang diaktifkan setiap kali perutean berubah:

 app.run(function ($rootScope, $state, $auth) { $rootScope.$on('$stateChangeStart', function (event, toState) { var requiredLogin = false; // check if this state need login if (toState.data && toState.data.requiredLogin) requiredLogin = true; // if yes and if this user is not logged in, redirect him to login page if (requiredLogin && !$auth.isAuthenticated()) { event.preventDefault(); $state.go('login'); } }); });

Sekarang, pengguna tidak bisa langsung masuk ke halaman rahasia tanpa login. Hore!

Seperti biasa, kode langkah ini dapat ditemukan di sini.

Langkah #4: Saatnya Mendapatkan Sesuatu yang Sangat Rahasia!

Pada saat ini, tidak ada yang benar-benar rahasia di halaman rahasia. Mari kita taruh sesuatu yang pribadi di sana.

Langkah ini dimulai dengan membuat titik akhir di back-end yang hanya dapat diakses oleh pengguna yang diautentikasi, seperti memiliki token yang valid. Titik akhir /pengguna di bawah ini mengembalikan user_id dan email pengguna yang sesuai dengan token.

 @app.route('/user') def user_info(): # the token is put in the Authorization header if not request.headers.get('Authorization'): return jsonify(error='Authorization header missing'), 401 # this header looks like this: “Authorization: Bearer {token}” token = request.headers.get('Authorization').split()[1] try: payload = jwt.decode(token, app.config['TOKEN_SECRET']) except DecodeError: return jsonify(error='Invalid token'), 401 except ExpiredSignature: return jsonify(error='Expired token'), 401 else: user_id = payload['sub'] user = User.query.filter_by(id=user_id).first() if user is None: return jsonify(error='Should not happen ...'), 500 return jsonify(id=user.id, email=user.email), 200 return jsonify(error="never reach here..."), 500

Sekali lagi, kami menggunakan modul jwt untuk memecahkan kode token JWT yang disertakan dalam header 'Otorisasi' dan untuk menangani kasus saat token kedaluwarsa atau tidak valid.

Mari kita uji titik akhir ini menggunakan curl. Pertama, kita perlu mendapatkan token yang valid:

 curl localhost:5000/auth/signup -H "Content-Type: application/json" -X POST -d '{"email":"[email protected]","password":"xyz"}'

Kemudian dengan token ini:

 curl localhost:5000/user -H "Authorization: Bearer {put the token here}"

Yang memberikan hasil ini:

 { "email": "[email protected]", "id": 1 }

Sekarang kita perlu memasukkan titik akhir ini ke dalam Secret Controller. Ini cukup sederhana karena kita hanya perlu memanggil titik akhir menggunakan modul $http biasa. Token secara otomatis dimasukkan ke header oleh Satellizer, jadi kita tidak perlu repot dengan semua detail menyimpan token dan kemudian meletakkannya di header kanan.

 getUserInfo(); function getUserInfo() { $http.get('/user') .then(function (response) { $scope.user = response.data; }) .catch(function (response) { console.log("getUserInfo error", response); }) }

Akhirnya, kami memiliki sesuatu yang benar-benar pribadi di halaman rahasia!

Halaman rahasia, menampilkan email dan id pengguna.

Kode langkah ini ada di GitHub.

Langkah #5: Login Facebook dengan Satellizer

Hal yang menyenangkan tentang Satellizer, seperti yang disebutkan di awal, adalah membuat integrasi login sosial menjadi jauh lebih mudah. Di akhir langkah ini, pengguna dapat masuk menggunakan akun Facebook mereka!

Otentikasi OAuth Facebook.

Hal pertama yang harus dilakukan adalah membuat aplikasi di halaman pengembang Facebook agar memiliki application_id dan kode rahasia. Silakan ikuti developers.facebook.com/docs/apps/register untuk membuat akun pengembang Facebook jika Anda belum memilikinya dan buat aplikasi situs web. Setelah itu, Anda akan memiliki ID aplikasi dan rahasia aplikasi seperti pada tangkapan layar di bawah ini.

Mendapatkan rahasia aplikasi.

Setelah pengguna memilih untuk terhubung dengan Facebook, Satellizer akan mengirimkan kode otorisasi ke titik akhir /auth/facebook . Dengan kode otorisasi ini, back-end dapat mengambil token akses dari Facebook /oauth endpoint yang memungkinkan panggilan ke Facebook Graph API untuk mendapatkan informasi pengguna seperti lokasi, teman_pengguna, email pengguna, dll.

Kami juga perlu melacak apakah akun pengguna dibuat dengan Facebook atau melalui pendaftaran biasa. Untuk melakukannya, kami menambahkan facebook_id ke model Pengguna kami.

 facebook_id = db.Column(db.String(100))

Rahasia facebook dikonfigurasi melalui variabel env FACEBOOK_SECRET yang kami tambahkan ke app.config .

 app.config['FACEBOOK_SECRET'] = os.environ.get('FACEBOOK_SECRET')

Jadi untuk meluncurkan app.py , Anda harus mengatur variabel env ini:

 FACEBOOK_SECRET={your secret} python app.py

Berikut adalah metode yang menangani login Facebook. Secara default Satellizer akan memanggil titik akhir /auth/facebook .

 @app.route('/auth/facebook', methods=['POST']) def auth_facebook(): access_token_url = 'https://graph.facebook.com/v2.3/oauth/access_token' graph_api_url = 'https://graph.facebook.com/v2.5/me?fields=id,email' params = { 'client_id': request.json['clientId'], 'redirect_uri': request.json['redirectUri'], 'client_secret': app.config['FACEBOOK_SECRET'], 'code': request.json['code'] } # Exchange authorization code for access token. r = requests.get(access_token_url, params=params) # use json.loads instead of urlparse.parse_qsl access_token = json.loads(r.text) # Step 2. Retrieve information about the current user. r = requests.get(graph_api_url, params=access_token) profile = json.loads(r.text) # Step 3. Create a new account or return an existing one. user = User.query.filter_by(facebook_id=profile['id']).first() if user: return jsonify(token=user.token()) u = User(facebook_id=profile['id'], email=profile['email']) db.session.add(u) db.session.commit() return jsonify(token=u.token())

Untuk mengirim permintaan ke server Facebook, kami menggunakan permintaan modul praktis. Sekarang bagian yang sulit di back-end sudah selesai. Di front-end, menambahkan login Facebook cukup sederhana. Pertama, kita perlu memberi tahu Satellizer facebook_id kita dengan menambahkan kode ini ke fungsi app.config :

 $authProvider.facebook({ clientId: {your facebook app id}, // by default, the redirect URI is http://localhost:5000 redirectUri: 'http://localhost:5000/static/index.html' });

Untuk login menggunakan Facebook, kita cukup memanggil:

 $auth.authenticate(“facebook”)

Seperti biasa, Anda dapat memeriksa kode di GitHub

Saat ini, webapp sudah lengkap dalam hal fungsionalitas. Pengguna dapat login/registrasi menggunakan email dan password biasa atau dengan menggunakan Facebook. Setelah login, pengguna dapat melihat halaman rahasianya.

Buat Antarmuka yang Cantik

Antarmuka tidak terlalu cantik pada saat ini, jadi mari tambahkan sedikit Bootstrap untuk tata letak dan modul pemanggang roti sudut untuk menangani pesan kesalahan dengan baik, seperti ketika login gagal.

Kode untuk bagian mempercantik ini dapat ditemukan di sini.

Kesimpulan

Artikel ini menunjukkan integrasi Satellizer selangkah demi selangkah dalam aplikasi web AngularJS (sederhana). Dengan Satellizer, kita dapat dengan mudah menambahkan login sosial lainnya seperti Twitter, Linkedin, dan lainnya. Kode di front-end hampir sama dengan di artikel. Namun, back-end bervariasi karena SDK jaringan sosial memiliki titik akhir yang berbeda dengan protokol yang berbeda. Anda dapat melihat https://github.com/sahat/satelizer/blob/master/examples/server/python/app.py yang berisi contoh untuk Facebook, Github, Google, Linkedin, Twiter, dan Bitbucket. Jika ragu, Anda harus melihat dokumentasi di https://github.com/sahat/satelizer.

Terkait: Login Satu-klik dengan Blockchain: Tutorial MetaMask