Integrating Facebook Login in AngularJS App with Satellizer
January 7, 2016 Comments Off on Integrating Facebook Login in AngularJS App with Satellizer 226 Views
<script src="bower_components/angular/angular.min.js"></script> <script src="bower_components/angular-ui-router/free up/angular-ui-router.min.js"></script> <script src="main.js"></script>
below is the code that we need in primary.js to configure routing:
var app = angular.module('DemoApp', ['ui.router']); app.config(function ($stateProvider, $urlRouterProvider) $stateProvider .state('residence', url: '/residence', templateUrl: 'partials/house.tpl.html' ) .state('secret', url: '/secret', templateUrl: 'partials/secret.tpl.html', ) .state('login', url: '/login', templateUrl: 'partials/login.tpl.html' ); $urlRouterProvider.in any other case('/home'); );
At this point in the event you run the server python app.py, you should have this common interface at
The hyperlinks residence, Login, and Secret must work at this level and convey the content material of the corresponding templates.
Congratulation, you simply finished putting in the skeleton! for those who come upon any error, please inspect the code on GitHub
Step #2: Login and Register
on the end of this step, you’ll have a webapp that you could register/login the usage of email and password.
the first step is to configure the backend. we’d like a consumer model and a strategy to generate the JWT token for a given person. The person version proven beneath is actually simplified and does no longer perform even any common exams similar to if container e mail accommodates “@”, or if container password accommodates as a minimum 6 characters, and so on.
type person(db.edition): identification = db.Column(db.Integer, primary_key=genuine) e mail = db.Column(db.String(a hundred), nullable=False) password = db.Column(db.String(one hundred)) 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')
We use the jwt module in python to generate the payload phase in JWT. The iat and exp part correspond to the timestamp that token is created and expired. in this code, the token shall be expired in 2 weeks.
After the variation user was once created, we are able to add the “login” and “register” endpoints. The code for both are reasonably identical, so right here i will just exhibit the “register” phase. Please notice that by using default, Satellizer will name the endpoints /auth/login and /auth/signup for the “login” and “register” respectively.
@app.route('/auth/signup', methods=['POST']) def signup(): data = request.json email = knowledge["email"] password = knowledge["password"] user = person(e mail=e-mail, password=password) db.session.add(user) db.session.commit() return jsonify(token=user.token())
Let’s test the endpoint the usage of curl first:
curl localhost:5000/auth/signup -H "content-type: application/json" -X submit -d '"e mail":"take a look at@abcd.com","password":"xyz"'
the result should seem like this:
"token": "very long string…."
Now that the again-finish section is ready, let’s attack the entrance-end! First, we wish to install satellizer and add it as a dependency in major.js:
bower install satellizer --retailer
Add satellizer as dependency:
var app = angular.module('DemoApp', ['ui.router', 'satellizer']);
Login and signup in satellizer is in fact rather simple compared to the entire setup unless now:
$scope.signUp = perform () $auth .signup(e mail: $scope.electronic mail, password: $scope.password) .then(function (response) // set the token bought from server $auth.setToken(response); // go to secret web page $state.go('secret'); ) .seize(function (response) console.log("error response", response); ) ;
if in case you have any problem putting in place the code, that you could check out the code on GitHub.
Step #three: but Secret View shouldn’t be in point of fact Secret, because any individual Can See It!
sure, that is correct! except now, any person can go to secret web page without logging in.
It’s time so as to add some interceptor in AngularJS to guarantee that if any person goes to secret web page and if this consumer shouldn’t be logged in, they will be redirected to the login page.
First, we must add a flag requiredLogin to tell apart secret web page from different ones.
.state('secret', url: '/secret', templateUrl: 'partials/secret.tpl.html', controller: 'SecretCtrl', information: requiredLogin: actual )
The “information” phase will probably be used within the $stateChangeStart event which is fired each time the routing changes:
app.run(perform ($rootScope, $state, $auth) $rootScope.$on('$stateChangeStart', perform (adventure, toState) var requiredLogin = false; // check if this state want login if (toState.data && toState.knowledge.requiredLogin) requiredLogin = actual; // if yes and if this consumer just isn't logged in, redirect him to login page if (requiredLogin && !$auth.isAuthenticated()) event.preventDefault(); $state.go('login'); ); );
Now, the person cannot go in an instant to the key page with out logging in. Hooray!
As ordinary, the code of this step will also be discovered here.
Step #four: It’s Time to Get one thing in point of fact Secret!
At this second, there’s nothing in point of fact secret in the secret web page. Let’s put one thing private there.
This step begins by using growing an endpoint in the back-finish which is simplest obtainable for an authenticated consumer, equivalent to having a legitimate token. The endpoint /user below returns the user_id and e-mail of the person similar to the token.
@app.route('/user') def user_info(): # the token is put in the Authorization header if no longer request.headers.get('Authorization'): return jsonify(error='Authorization header lacking'), 401 # this header looks like this: “Authorization: Bearer token” token = request.headers.get('Authorization').cut up()[1] are attempting: payload = jwt.decode(token, app.config['TOKEN_SECRET']) apart from DecodeError: return jsonify(error='Invalid token'), 401 except for ExpiredSignature: return jsonify(error='Expired token'), 401 else: user_id = payload['sub'] user = consumer.question.filter_by(id=user_id).first() if consumer is None: return jsonify(error='will have to now not happen ...'), 500 return jsonify(id=person.identity, e-mail=consumer.e mail), 200 return jsonify(error="by no means reach right here..."), 500
again, we make use of the module jwt to decode the JWT token integrated in the ‘Authorization’ header and to handle the case when the token is expired or now not valid.
Let’s take a look at this endpoint the usage of curl. First, we want to get a sound token:
curl localhost:5000/auth/signup -H "content-sort: utility/json" -X publish -d '"email":"test@abcd.com","password":"xyz"'
Then with this token:
curl localhost:5000/person -H "Authorization: Bearer put the token right here"
which gives this consequence:
"e mail": "check@abcd.com", "id": 1
Now we need to embrace this endpoint within the Secret Controller. this is relatively easy as we simply need to call the endpoint the use of the common $http module. The token is mechanically inserted to the header by means of Satellizer, so we don’t need to trouble with all the important points of saving the token and then putting it in the right header.
getUserInfo(); operate getUserInfo() $http.get('/person') .then(operate (response) $scope.person = response.data; ) .trap(function (response) console.log("getUserInfo error", response); )
finally, we have now something actually personal in the secret page!
The code of this step is on GitHub.
Step #5: facebook Login with Satellizer
a nice thing about Satellizer, as mentioned at the start, is it makes integrating social login loads more straightforward. on the end of this step, users can login using their facebook account!
first thing to do is to create an application on fb developers page in an effort to have an application_id and a secret code. Please follow developers.fb.com/doctors/apps/register to create a facebook developer account for those who don’t have one already and create a web page app. After that, you are going to have the applying identity and utility secret as in the screenshot below.
as soon as the consumer chooses to connect with fb, Satellizer will send an authorization code to the endpoint /auth/facebook. With this authorization code, the back-end can retrieve an get entry to token from fb /oauth endpoint that permits the call to fb Graph API to get consumer information akin to area, user_friends, person electronic mail, and many others.
We additionally want to maintain track of whether or not a user account is created with facebook or via common signup. to do so, we add facebook_id to our user version.
facebook_id = db.Column(db.String(one hundred))
The facebook secret’s configured via env variables FACEBOOK_SECRET that we add to app.config.
app.config['FACEBOOK_SECRET'] = os.environ.get('FACEBOOK_SECRET')
so that you can launch the app.py, you will have to set this env variable:
FACEBOOK_SECRET=your secret python app.py
right here is the tactic which handles facebook logins. with the aid of default Satellizer will call the endpoint /auth/facebook.
@app.route('/auth/facebook', methods=['POST']) def auth_facebook(): access_token_url = ' graph_api_url = ' 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 get admission to token. r = requests.get(access_token_url, params=params) # use json.loads as a substitute of urlparse.parse_qsl access_token = json.hundreds(r.textual content) # Step 2. Retrieve details about the current user. r = requests.get(graph_api_url, params=access_token) profile = json.masses(r.textual content) # Step three. Create a brand new account or return an present one. user = user.question.filter_by(facebook_id=profile['id']).first() if user: return jsonify(token=consumer.token()) u = user(facebook_id=profile['id'], email=profile['email'])db.session.add(u) db.session.commit() return jsonify(token=u.token())
To ship a request to the fb server, we use the to hand module requests. Now the tough section on the again-finish is done. On the entrance-end, adding fb login is rather easy. First, we need to inform Satellizer our facebook_id with the aid of adding this code into app.config operate:
$authProvider.fb( clientId: your fb app identification, // by default, the redirect URI is redirectUri: ' );
To login the usage of facebook, we are able to just call:
$auth.authenticate(“facebook”)
As normal, which you could take a look at the code on GitHub
at this time, the webapp is full relating to performance. The consumer can login/register the usage of regular e mail and password or by way of using facebook. once logged in, the user can see his secret page.
Make an attractive Interface
The interface shouldn’t be very lovely at this point, so let’s add a bit of bit of Bootstrap for the format and the angular toaster module to deal with an error message effectively, corresponding to when login fails.
The code for this beautifying section can be found here.
Conclusion
this article presentations a step-by way of-step integration of Satellizer in a (simple) AngularJS webapp. With Satellizer, we will simply add other social logins reminiscent of Twitter, Linkedin, and more. The code on the entrance-end is relatively the identical as in the article. then again, the back-end varies as social network SDKs have different endpoints with completely different protocols. that you could take a look at which incorporates examples for fb, Github, Google, Linkedin, Twiter and Bitbucket. When unsure, you must check out the documentation on