Integrarea login-ului Facebook în aplicația AngularJS cu Satellizer

Publicat: 2022-03-11

Odată cu apariția cadrelor front-end bogate în funcții, cum ar fi AngularJS, din ce în ce mai multă logică este implementată pe front-end, cum ar fi manipularea/validarea datelor, autentificarea și multe altele. Satellizer, un modul de autentificare bazat pe token ușor de utilizat pentru AngularJS, simplifică procesul de implementare a mecanismului de autentificare în AngularJS. Biblioteca vine cu suport încorporat pentru Google, Facebook, LinkedIn, Twitter, Instagram, GitHub, Bitbucket, Yahoo, Twitch , și conturi Microsoft (Windows Live).

În acest articol, vom construi o aplicație web foarte simplă, similară celei de aici, care vă permite să vă autentificați și să vedeți informațiile utilizatorului curent.

Autentificare vs Autorizare

Acestea sunt 2 cuvinte înfricoșătoare pe care le întâlniți adesea odată ce aplicația dvs. începe să integreze un sistem de utilizator. Conform Wikipedia:

Autentificarea este actul de confirmare a adevărului unui atribut al unei singure date (un datum) susținut de o entitate.

Autorizarea este funcția de specificare a drepturilor de acces la resursele legate de securitatea informațiilor și securitatea informatică în general și de controlul accesului în special.

În termeni profani, să luăm un exemplu de site web de blog cu unii oameni care lucrează la el. Bloggerii scriu articole, iar managerul validează conținutul. Fiecare persoană se poate autentifica (autentifica) în sistem, dar drepturile sale (autorizarea) sunt diferite, astfel încât bloggerul nu poate valida conținutul, în timp ce managerul poate.

De ce Satellizer

Vă puteți crea propriul sistem de autentificare în AngularJS urmând câteva tutoriale precum acesta foarte detaliat: Tutorial JSON Web Token: Un exemplu în Laravel și AngularJS. Vă sugerez să citiți acest articol deoarece explică foarte bine JWT (JSON Web Token) și arată o modalitate simplă de a implementa autentificarea în AngularJS folosind direct stocarea locală și interceptoarele HTTP.

Deci de ce Satellizer? Motivul principal este că acceptă câteva autentificări la rețelele sociale, cum ar fi Facebook, Twitter etc. În zilele noastre, în special pentru site-urile web utilizate pe mobil, introducerea numelui de utilizator și a parolei este destul de greoaie, iar utilizatorii se așteaptă să poată utiliza site-ul dvs. cu puține piedici. prin utilizarea autentificărilor sociale. Întrucât integrarea SDK-ului fiecărei rețele sociale și urmărirea documentațiilor acestora este destul de repetitivă, ar fi bine să susțineți aceste conectări sociale cu un efort minim.

Mai mult, Satellizer este un proiect activ pe Github. Activ este esențial aici, deoarece aceste SDK-uri se schimbă destul de frecvent și nu doriți să citiți documentația lor din când în când (oricine lucrează cu Facebook SDK știe cât de enervant este)

Aplicația AngularJS cu conectare pe Facebook

Aici lucrurile încep să devină interesante.

Vom construi o aplicație web care are un mecanism obișnuit de autentificare/înregistrare (adică folosind nume de utilizator, parolă) și care acceptă, de asemenea, conectări sociale. Această aplicație web este foarte simplă, deoarece are doar 3 pagini:

  • Pagina principală: oricine poate vedea
  • Pagina de autentificare: pentru a introduce numele de utilizator/parola
  • Pagina secretă: pe care doar utilizatorii conectați o pot vedea

Pentru backend, vom folosi Python și Flask. Python și framework-ul Flask sunt destul de expresive, așa că sper că portarea codului în alte limbi/framework-uri nu va fi foarte dificilă. Desigur, vom folosi AngularJS pentru front-end. Iar pentru autentificarea socială, ne vom integra cu Facebook doar deoarece este cea mai populară rețea socială în acest moment.

Să începem!

Pasul #1: Proiectul Bootstrap

Iată cum ne vom structura codul:

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

Tot codul back-end este în app.py . Codul front-end este pus în folderul static/. În mod implicit, Flask va servi automat conținutul folderului static/. Toate vizualizările parțiale sunt în static/partials/ și gestionate de modulul ui.router.

Pentru a începe codificarea back-end-ului, vom avea nevoie de Python 2.7.* și vom instala bibliotecile necesare folosind pip. Desigur, puteți utiliza virtualenv pentru a izola un mediu Python. Mai jos este lista modulelor Python necesare pentru a le pune în requirements.txt:

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

Pentru a instala toate aceste dependențe:

 pip install -r requirements.txt

În app.py avem un cod inițial pentru a bootstrap Flask (instrucțiunile de import sunt omise pentru concizie):

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

Apoi pornim Bower și instalăm AngularJS și 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

Odată ce aceste biblioteci sunt instalate, trebuie să includem AngularJS și ui-router în index.html și să creăm rute pentru 3 pagini: home, login și secret.

 <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>

Mai jos este codul de care avem nevoie în main.js pentru a configura rutarea:

 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'); });

În acest moment, dacă rulați serverul python app.py , ar trebui să aveți această interfață de bază la http://localhost:5000

Interfață de conectare de bază

Linkurile Acasă, Conectare și Secret ar trebui să funcționeze în acest moment și să arate conținutul șabloanelor corespunzătoare.

Felicitări, tocmai ați terminat de montat scheletul! Dacă întâmpinați vreo eroare, vă rugăm să verificați codul de pe GitHub

Pasul #2: Conectați-vă și Înregistrați-vă

La sfârșitul acestui pas, veți avea o aplicație web pe care o puteți înregistra/autentifica folosind e-mail și parola.

Primul pas este configurarea backend-ului. Avem nevoie de un model de utilizator și de o modalitate de a genera simbolul JWT pentru un anumit utilizator. Modelul de utilizator prezentat mai jos este cu adevărat simplificat și nu efectuează nici măcar verificări de bază, cum ar fi dacă e-mailul de câmp conține „@”, sau dacă parola de câmp conține cel puțin 6 caractere etc.

 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')

Folosim modulul jwt din python pentru a genera partea de sarcină utilă în JWT. Partea iat și exp corespund marcajului de timp pentru care simbolul este creat și expirat. În acest cod, jetonul va fi expirat în 2 săptămâni.

După ce modelul User a fost creat, putem adăuga punctele finale „login” și „înregistrare”. Codul pentru ambele sunt destul de similare, așa că aici voi arăta doar partea „înregistrare”. Vă rugăm să rețineți că, în mod implicit, Satellizer va apela punctele finale /auth/login și /auth/signup pentru „login” și, respectiv, „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())

Să verificăm punctul final folosind curl mai întâi:

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

Rezultatul ar trebui să arate astfel:

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

Acum că partea de back-end este gata, să atacăm front-end-ul! Mai întâi, trebuie să instalăm Satellizer și să-l adăugăm ca dependență în main.js:

 bower install satellizer --save

Adăugați satellizer ca dependență:

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

Conectarea și înregistrarea în Satellizer sunt de fapt destul de simple în comparație cu toate configurațiile de până acum:

 $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); }) };

Dacă întâmpinați dificultăți la configurarea codului, puteți arunca o privire la codul de pe GitHub.

Pasul #3: Dar Vederea Secretă nu este cu adevărat secretă, deoarece oricine o poate vedea!

Da, este corect! Până acum, oricine poate accesa pagina secretă fără a se autentifica.

Este timpul să adăugați un interceptor în AngularJS pentru a vă asigura că, dacă cineva merge pe pagina secretă și dacă acest utilizator nu este autentificat, va fi redirecționat către pagina de autentificare.

În primul rând, ar trebui să adăugăm un steag obligatoriu de conectare pentru a distinge pagina secretă de celelalte.

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

Partea „date” va fi folosită în evenimentul $stateChangeStart, care este declanșat de fiecare dată când se schimbă rutarea:

 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'); } }); });

Acum, utilizatorul nu poate merge direct la pagina secretă fără a se autentifica. Ura!

Ca de obicei, codul acestui pas poate fi găsit aici.

Pasul #4: Este timpul să obțineți ceva cu adevărat secret!

În acest moment, nu există nimic cu adevărat secret în pagina secretă. Să punem ceva personal acolo.

Acest pas începe prin crearea unui punct final în back-end, care este accesibil numai pentru un utilizator autentificat, cum ar fi un token valid. Punctul final / utilizatorul de mai jos returnează user_id -ul și e- mailul utilizatorului corespunzător jetonului.

 @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

Din nou, folosim modulul jwt pentru a decoda jetonul JWT inclus în antetul „Autorizare” și pentru a gestiona cazul în care jetonul este expirat sau nu este valabil.

Să testăm acest punct final folosind curl. În primul rând, trebuie să obținem un simbol valid:

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

Apoi cu acest simbol:

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

Ceea ce dă acest rezultat:

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

Acum trebuie să includem acest punct final în Controlerul Secret. Acest lucru este destul de simplu, deoarece trebuie doar să apelăm punctul final folosind modulul $http obișnuit. Tokenul este inserat automat în antet de către Satellizer, așa că nu trebuie să ne obosim cu toate detaliile de salvare a jetonului și apoi de a-l pune în antetul din dreapta.

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

În sfârșit, avem ceva cu adevărat personal în pagina secretă!

Pagina secretă, afișând un e-mail și un ID de utilizator.

Codul acestui pas este pe GitHub.

Pasul #5: Conectați-vă la Facebook cu Satellizer

Un lucru bun despre Satellizer, așa cum am menționat la început, este că face integrarea autentificărilor sociale mult mai ușoară. La sfârșitul acestui pas, utilizatorii se pot autentifica folosind contul lor de Facebook!

Autentificare Facebook OAuth.

Primul lucru de făcut este să creați o aplicație pe pagina dezvoltatorilor Facebook pentru a avea un application_id și un cod secret. Vă rugăm să urmați developers.facebook.com/docs/apps/register pentru a crea un cont de dezvoltator Facebook dacă nu aveți deja unul și creați o aplicație pentru site-ul web. După aceea, veți avea ID-ul aplicației și secretul aplicației, ca în captura de ecran de mai jos.

Obținerea secretului aplicației.

Odată ce utilizatorul alege să se conecteze la Facebook, Satellizer va trimite un cod de autorizare către punctul final /auth/facebook . Cu acest cod de autorizare, back-end-ul poate prelua un jeton de acces de la punctul final Facebook /oauth care permite apelului la Facebook Graph API pentru a obține informații despre utilizator, cum ar fi locația, user_friends, e-mailul utilizatorului etc.

De asemenea, trebuie să urmărim dacă un cont de utilizator este creat cu Facebook sau prin înregistrarea obișnuită. Pentru a face acest lucru, adăugăm facebook_id la modelul nostru de utilizator.

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

Secretul Facebook este configurat prin variabilele env FACEBOOK_SECRET pe care le adăugăm la app.config .

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

Deci, pentru a lansa app.py , ar trebui să setați această variabilă env:

 FACEBOOK_SECRET={your secret} python app.py

Iată metoda care gestionează conectările Facebook. În mod implicit, Satellizer va apela punctul final /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())

Pentru a trimite o solicitare către serverul Facebook, folosim cererile de module la îndemână. Acum partea dificilă din back-end este gata. Pe front-end, adăugarea de autentificare Facebook este destul de simplă. În primul rând, trebuie să îi spunem lui Satellizer facebook_id -ul nostru adăugând acest cod în funcția 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' });

Pentru a vă autentifica folosind Facebook, putem doar să sunăm:

 $auth.authenticate(“facebook”)

Ca de obicei, puteți verifica codul pe GitHub

În acest moment, aplicația web este completă din punct de vedere al funcționalității. Utilizatorul se poate autentifica/înregistra folosind e-mailul și parola obișnuite sau folosind Facebook. Odată autentificat, utilizatorul își poate vedea pagina secretă.

Faceți o interfață drăguță

Interfața nu este foarte frumoasă în acest moment, așa că să adăugăm puțin Bootstrap pentru aspect și modulul de pâine unghiular pentru a gestiona frumos un mesaj de eroare, cum ar fi atunci când autentificarea eșuează.

Codul pentru această parte de înfrumusețare poate fi găsit aici.

Concluzie

Acest articol arată o integrare pas cu pas a Satellizer într-o aplicație web AngularJS (simpluă). Cu Satellizer, putem adăuga cu ușurință alte date de conectare sociale, cum ar fi Twitter, Linkedin și multe altele. Codul de pe front-end este aproape același ca în articol. Cu toate acestea, back-end-ul variază, deoarece SDK-urile rețelelor sociale au puncte finale diferite cu protocoale diferite. Puteți arunca o privire la https://github.com/sahat/satellizer/blob/master/examples/server/python/app.py care conține exemple pentru Facebook, Github, Google, Linkedin, Twiter și Bitbucket. Când aveți îndoieli, ar trebui să aruncați o privire la documentația de pe https://github.com/sahat/satellizer.

Înrudit : Conectare cu un singur clic cu Blockchain: Un tutorial MetaMask