С пристигането на богати на функции интерфейсни рамки като AngularJS, все повече и повече логика се внедрява във фронт-енда, като манипулиране / валидиране на данни, удостоверяване и др. Satellizer, лесен за използване модул за удостоверяване, базиран на маркери за AngularJS, опростява процеса на внедряване на механизма за удостоверяване в AngularJS, Библиотеката се предлага с вградена поддръжка за Google, Facebook, LinkedIn, Twitter, Instagram, GitHub, Bitbucket, Yahoo, Twitch и акаунти в Microsoft (Windows Live).
В тази статия ще изградим много просто уеб приложение, подобно на това тук което ви позволява да влезете и да видите информация за текущия потребител.
Това са 2 страшни думи, които често срещате, след като приложението ви започне да интегрира потребителска система. Според Уикипедия:
Удостоверяване е актът за потвърждаване на истинността на атрибут на единична част от данните (данните), за които се твърди, че са верни от обект.
Разрешение е функцията за определяне на правата за достъп до ресурси, свързани с информационната сигурност и компютърната сигурност като цяло и по-специално с контрола на достъпа.
От гледна точка на неспециалистите, нека да вземем пример за уебсайт на блог с някои хора, работещи върху него. Блогерите пишат статии, а мениджърът потвърждава съдържанието. Всеки човек може да удостоверява (влизане) в системата, но правата му (упълномощаване) са различни, така че блогърът не може да проверява съдържанието, докато мениджърът може.
Можете да създадете своя собствена система за удостоверяване в AngularJS, като следвате някои уроци като този много подробен: Урок за JSON Web Token: Пример за Laravel и AngularJS . Предлагам да прочетете тази статия, тъй като тя много добре обяснява JWT (JSON Web Token) и показва лесен начин за внедряване на удостоверяване в AngularJS, използвайки директно локалното хранилище и HTTP прехващачите.
И така, защо Satellizer? Основната причина е, че поддържа няколко входа за социални мрежи като Facebook, Twitter и др. В днешно време, особено за уебсайтове, използвани на мобилни устройства, въвеждането на потребителско име и парола е доста тромаво и потребителите очакват да могат да използват уебсайта Ви с малко препятствия чрез използване на социални входни данни. Тъй като интегрирането на SDK на всяка социална мрежа и следването на техните документации е доста повтарящо се, би било хубаво да подкрепите тези социални влизания с минимални усилия.
Освен това Satellizer е активен проект за Github. Активното е ключово тук, тъй като тези SDK се сменят доста често и не искате да четете документацията им от време на време (всеки, който работи с Facebook SDK, знае колко досадно е)
Тук нещата започват да стават интересни.
Ще изградим уеб приложение, което има редовен механизъм за влизане / регистрация (т.е. с помощта на потребителско име, парола) и поддържа социални входни данни. Това уеб приложение е много просто, тъй като има само 3 страници:
За бекенда ще използваме Python и Flask. Python и framework Flask са доста изразителни, така че се надявам пренасянето на кода на други езици / рамки да не е много трудно. Ние, разбира се, ще използваме AngularJS за предния край. А за социалните влизания ще се интегрираме само с Facebook, тъй като той е най-популярната социална мрежа в момента.
Да започваме!
Ето как ще структурираме нашия код:
- app.py - static/ - index.html - app.js - bower.json - partials/ - login.tpl.html - home.tpl.html - secret.tpl.html
Целият вътрешен код е в app.py . Кодът отпред се поставя в static / folder. По подразбиране Flask автоматично ще обслужва съдържанието на static / folder. Всички частични изгледи са в статични / частични / и се обработват от модула ui.router.
За да започнем да кодираме back-end, ще ни трябва Python 2.7. * И ще инсталираме необходимите библиотеки с помощта на pip. Можете, разбира се, да използвате virtualenv за изолиране на среда на Python. По-долу е списъкът на необходимите модули на Python, които трябва да се въведат в requirements.txt:
Flask==0.10.1 PyJWT==1.4.0 Flask-SQLAlchemy==1.0 requests==2.7.0
За да инсталирате всички тези зависимости:
pip install -r requirements.txt
В app.py имаме първоначален код за стартиране на Flask (операторите за импортиране са пропуснати за краткост):
app = Flask(__name__) @app.route('/') def index(): return flask.redirect('/static/index.html') if __name__ == '__main__': app.run(debug=True)
След това ние в него bower и инсталирайте AngularJS и 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
След като тези библиотеки са инсталирани, трябва да включим AngularJS и ui-router в index.html и създайте маршрути за 3 страници: начало, вход и тайна.
Home Login Secret
По-долу е кодът, който ни е необходим в main.js за конфигуриране на маршрутизация:
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'); });
В този момент, ако стартирате сървъра python app.py , трябва да имате този основен интерфейс на http: // localhost: 5000
Връзките Home, Login и Secret трябва да работят в този момент и да показват съдържанието на съответните шаблони.
Поздравления, току-що приключихте с настройката на скелета! Ако срещнете някаква грешка, моля, проверете код на GitHub
В края на тази стъпка ще имате уеб приложение, което можете да регистрирате / влезете с имейл и парола.
Първата стъпка е да конфигурирате бекенда. Нуждаем се от потребителски модел и начин за генериране на JWT токен за даден потребител. Потребителският модел, показан по-долу, е наистина опростен и не извършва дори никакви основни проверки, като например полето електронна поща съдържа „@“, или ако поле парола съдържа поне 6 знака и т.н.
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')
Използваме модула jwt в python, за да генерираме частта от полезния товар в JWT. Частта iat и exp съответстват на клеймото за време, че маркерът е създаден и е изтекъл. В този код токенът ще изтече след 2 седмици.
След създаването на модела Потребител можем да добавим крайните точки „влизане“ и „регистрация“. Кодът и за двата са доста сходни, така че тук просто ще покажа частта „регистър“. Моля, обърнете внимание, че по подразбиране Satellizer ще извика крайните точки / auth / login и / auth / регистрация за „вход“ и „регистрация“ съответно.
@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())
Нека първо проверим крайната точка, като използваме curl:
curl localhost:5000/auth/signup -H 'Content-Type: application/json' -X POST -d '{'email':' [email protected] ','password':'xyz'}'
Резултатът трябва да изглежда така:
{ 'token': 'very long string….' }
Сега, когато задната част е готова, нека атакуваме предния край! Първо, трябва да инсталираме сателизатора и да го добавим като зависимост в main.js:
bower install satellizer --save
Добавете сателит като зависимост:
var app = angular.module('DemoApp', ['ui.router', 'satellizer']);
Влизането и регистрацията в сателитора всъщност е доста проста в сравнение с всички настройки досега:
$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); }) };
Ако имате затруднения с настройването на кода, можете да разгледате код на GitHub .
Да това е вярно! Досега всеки може да отиде на секретна страница, без да влиза.
Време е да добавите прехващач в AngularJS, за да сте сигурни, че ако някой отиде на секретна страница и ако този потребител не е влязъл, той ще бъде пренасочен към страницата за вход.
Първо, трябва да добавим флаг requiredLogin, за да разграничим тайната страница от другите.
.state('secret', { url: '/secret', templateUrl: 'partials/secret.tpl.html', controller: 'SecretCtrl', data: {requiredLogin: true} })
Частта „данни“ ще бъде използвана в събитието $ stateChangeStart, което се задейства всеки път, когато маршрутизацията се промени:
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'); } }); });
Сега потребителят не може да отиде директно на тайната страница, без да влезе. Ура!
Както обикновено, кодът на тази стъпка може да бъде намерен тук .
В този момент в тайната страница няма нищо наистина тайно. Нека поставим нещо лично там.
Тази стъпка започва чрез създаване на крайна точка в задната част, която е достъпна само за удостоверен потребител, като например да има валиден маркер. Крайната точка / потребител отдолу връща user_id и електронна поща на потребителя, съответстващ на маркера.
@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
Отново използваме модула jwt за декодиране на JWT маркера, включен в заглавката ‘Authorization’ и за обработка на случая, когато токенът е изтекъл или не е валиден.
Нека тестваме тази крайна точка, използвайки curl. Първо, трябва да получим валиден токен:
curl localhost:5000/auth/signup -H 'Content-Type: application/json' -X POST -d '{'email':' [email protected] ','password':'xyz'}'
След това с този знак:
curl localhost:5000/user -H 'Authorization: Bearer {put the token here}'
Което дава този резултат:
как да изчислим цената на кол опцията
{ 'email': ' [email protected] ', 'id': 1 }
Сега трябва да включим тази крайна точка в Secret Controller. Това е съвсем просто, тъй като просто трябва да извикаме крайната точка, използвайки обикновения $ http модул. Токенът се вмъква автоматично в заглавката от Satellizer, така че не е нужно да се занимаваме с всички подробности за запазването на маркера и след това да го поставим в десния заглавие.
getUserInfo(); function getUserInfo() { $http.get('/user') .then(function (response) { $scope.user = response.data; }) .catch(function (response) { console.log('getUserInfo error', response); }) }
И накрая, имаме нещо наистина лично в тайната страница!
Кодът на тази стъпка е включен GitHub .
Хубавото на Satellizer, както беше споменато в началото, е, че прави интегрирането на социалното влизане много по-лесно. В края на тази стъпка потребителите могат да влязат, използвайки своя Facebook акаунт!
Първото нещо, което трябва да направите, е да създадете приложение на страницата за разработчици на Facebook, за да имате application_id и таен код. Моля последвайте developers.facebook.com/docs/apps/register да създадете акаунт за разработчици във Facebook, ако вече нямате такъв, и да създадете приложение за уебсайт. След това ще имате идентификатора на приложението и тайната на приложението, както е показано на екранната снимка по-долу.
След като потребителят избере да се свърже с Facebook, Satellizer ще изпрати код за оторизация до крайната точка / auth / facebook . С този код за оторизация, back-endът може да извлече токен за достъп от Facebook / oauth крайна точка, която позволява на обаждането до Facebook Graph API да получи потребителска информация като местоположение, user_friends, потребителски имейл и т.н.
Също така трябва да следим дали потребителски акаунт е създаден с Facebook или чрез редовна регистрация. За целта добавяме facebook_id към нашия Потребителски модел.
facebook_id = db.Column(db.String(100))
Тайната на facebook е конфигурирана чрез env променливи FACEBOOK_SECRET, които добавяме app.config .
app.config['FACEBOOK_SECRET'] = os.environ.get('FACEBOOK_SECRET')
Така че да стартирате app.py , трябва да зададете тази env променлива:
FACEBOOK_SECRET={your secret} python app.py
Ето метода, който обработва влизанията във Facebook. По подразбиране Satellizer ще извика крайната точка / 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())
За да изпратим заявка до сървъра на Facebook, използваме удобните заявки за модул. Сега сложната част от задния край е свършена. Отпред добавянето на вход за Facebook е съвсем просто. Първо, трябва да кажем на Satellizer нашия facebook_id чрез добавяне на този код в 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' });
За да влезете с Facebook, можем просто да се обадим:
$auth.authenticate(“facebook”)
Както обикновено, можете да проверите код на GitHub
Понастоящем webapp е пълен по отношение на функционалността. Потребителят може да влезе / да се регистрира, като използва обикновени имейл и парола или чрез Facebook. След като влезе, потребителят може да види тайната си страница.
В този момент интерфейсът не е много красив, така че нека добавим малко Bootstrap за оформлението и модула на ъгловия тостер, за да се справим добре със съобщението за грешка, като например при неуспешно влизане.
Кодът за тази разкрасяваща част може да бъде намерен тук .
Тази статия показва поетапна интеграция на Satellizer в (просто) уебсайт AngularJS. С Satellizer можем лесно да добавяме други социални влизания като Twitter, Linkedin и др. Кодът отпред е съвсем същият като в статията. Задният край обаче варира, тъй като SDK на социалните мрежи имат различни крайни точки с различни протоколи. Можете да разгледате https://github.com/sahat/satellizer/blob/master/examples/server/python/app.py, който съдържа примери за Facebook, Github, Google, Linkedin, Twiter и Bitbucket. Когато се съмнявате, трябва да разгледате документацията на https://github.com/sahat/satellizer .
Свързани: Влизане с едно кликване с Blockchain: Урок за MetaMask