Angular authorization depending on url parameters - javascript

I am building an angular application, I need to build a login module and I found this article: angular-auth
It seems ok, but I can't figure out how to authorize users depending on url parameters. For exmaple I have this route:
$routeProvider.when('/client_details/:clientId', {
templateUrl: 'client_details/client_details.html',
controller: 'clientDetailsCtrl'
});
I need to check that you can see the client details only if the client belongs to your list of clients. Otherwise I can just try random ids to see random clients page.
How can I do that?

Related

Manually Login by Facebook in Angular6 and Laravel

I'm developing an application which I'm writing in Angular 6 framework.
Currently, I would like to add user login by social media like: Facebook, Google, Twitter, Github, LinkedIn.
I have a four buttons for these actions in my SocialLoginComponent's template:
Now I'm trying to implement user login by facebook after clicking on CONNECT WITH FACEBOOK button which has an click angular action:
<button (click) = "loginWithFacebook()" class="social-button" id="facebook-connect"> <span>Connect with Facebook</span></button>
Implementation of function loginWithFacebook looks like:
loginWithFacebook() {
this.auth.loginByFacebook(this.apiKey, this.redirectUri).subscribe({
next: (v) => console.log(v)
});
}
Here auth is of course service injected by constructor:
constructor(private auth: AuthService) {
}
Below I show implementation method loginByFacebook method in my AuthService:
loginByFacebook(appId, redirectUri) {
const facebookParams = new HttpParams()
.set('client_id', appId)
.set('redirect_uri', redirectUri)
.set('response_type', 'token');
return this.http.get(this.facebookUrl, {params : facebookParams});
});
where facebookUrl is the AuthService property:
private facebookUrl = 'https://www.facebook.com/v3.1/dialog/oauth';
I'm setting up here of course parameters based on My Facebook App.
I'm trying to invoke that url by get method in order to obtain a facebook login dialog based on description from tutorial: manualyBuildALoginFlow. I wouldn't like to use JavaScript SDK in my solution.
In current state when I'm clicking on the faecebook button, there is response like below:
I would like to obtain modal dialog with confirmation like below:
In my Get request I add parameter response_type = token in order to obtain Social token. On the below diagram I show what flow I'm trying to achieve:
On above diagram my server is laravel framework which currently handle user login and returns JWT token in order to check that user's logged in to application. Next this token I save in local storage by Angular6 framework.
How could I obtain that redirection with modal window in Angular6? What I'm doing wrong is that redirection dosen't work? What first step should I do in order to implement such authorization using facebook?
I would be greateful for advices.
Best Regards
I'm trying to invoke that url by get method
Which means an AJAX request … and that is of course not possible.
You need to redirect the user to the login dialog URL, not try and request it in the background - for the simple reason, that users need to be able to verify via the browser address bar, that they are indeed entering their login credentials to Facebook, and not some phishing site. If you requested it via AJAX and displayed it “within” your page, that would not be possible.
I've implemented method as misorude suggests in my Auth Service:
loginWithFacebook(appId: number, redirectUri: string) {
window.location.href = `https://www.facebook.com/v3.1/dialog/oauth?client_id=${appId}&redirect_uri=${redirectUri}&response_type=token&display=popup`;
}
Currently the page redirects to my Facebook app. Next I confirm my login by Facebook in dialog window. Then browser redirect back to my Angular app and in my url I have Social token from Facebook like on the picture below:
Next I'd like to obtain this token from url and then to implement the data flow as below:
How should I correctly get an access token and post to my backend Server as on the schema above?
I would be greateful for help
Best regards

Angular route parameter causing site to crash then redirect

I've been working on this project and we are working in Angular 1.6. I've done routes and route parameters before. Mind you I was brought in to this project as a consultant, so I'm going with what they wrote, and it's been, let's just say, interesting.
Problem
URL format:
https://{baseurl}/#/newPassword/{authstring}
This is the URL that is getting clicked from a validation e-mail sent to a client when they request to change their password. Use your imagination to fill in content, as the bracket notation are placeholders for security purposes.
authstring is your standard encryption, base64/md5 I'm not exactly sure, probably md5. So there is nothing special.
When passing to the route of newPassword, the route crashes, and then it is immediately redirected to the home page of the site and a standard Windows Authentication box pops up. As seen in the image below.
I have no idea why this is showing up, as there is no call for it in the code anywhere to my knowledge, and this has been confirmed by other sources. It's not an IIS issue either, I have already confirmed that too. So there are two items out. The other interesting issue is why is it redirecting as well. The route clearly exists.
Change Password Controller and Route Code
In order to see if the current controller was the issue, I broke the controller down to it's most basic format and did a console log on $routeParams to see if anything changed. The same error occurs.
Here is the controller code I tested with:
angular.module('app').controller('newPasswordController', function ($scope, $route, $routeParams) {
console.log($routeParams);
});
Here is what the route looks like in the router file:
.when("/newPassword/:auth", {
templateUrl: "newPassword/new-password.html",
controller: 'newPasswordController',
})
What am I doing wrong?

Facebook javascript api - One or more of the given URLs is not allowed by the App's settings

I have a simple application that I'm hosting on bluemix.
I have set up a Single Sign On service for my application and paired it with facebook. I can successfully log in using the SSO service from bluemix and then I want to check that status of my login (I am logged in or not).
function CheckStatus(){
console.log("I'm trying to check the status");
FB.getLoginStatus(function(response) {
console.log("Here is the status response:");
console.log(response.status);
});
}
I trigger this piece of code with a simple button defined before. Whenever I click the code I get the following error:
Given URL is not permitted by the application configuration.: One or more of the given URLs is not allowed by the App's settings. It
must match the Website URL or Canvas URL, or the domain must be a
subdomain of one of the App's domains.
I had a look at a number of posts on stackoverflow about this and none of them seem to work. My understanding is that there is something wrong with the configuration of my application but I can't figure out what.
Below is my configuration:
And this is the url my application is trying to reach when I try to get my login status:
https://www.facebook.com/connect/ping?client_id=913147408730179&domain=fncsecuritydemo.mybluemix.net&origin=1&redirect_uri=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FrFG58m7xAig.js%3Fversion%3D41%23cb%3Df29b5c6b3%26domain%3Dfncsecuritydemo.mybluemix.net%26origin%3Dhttp%253A%252F%252Ffncsecuritydemo.mybluemix.net%252Ff21657f8dc%26relation%3Dparent&response_type=token%2Csigned_request%2Ccode&sdk=joey
I am out of ideas about what I should be trying next. Any help is very much apreaciated. Let me know if you need more info.
The answer for this error lies in the Valid OAuth redirect URIs that fall under the Advanced tab from settings.
While setting up the application profile on facebook I have set the Valid OAuth redirect URIs to an URL generated by bluemix.
In order to received response on my application I had to add my app url in there as well. Rookie mistake.

AngularJS oauth endpoint with hash in url (SpotifyAPI)

I want to receive the oauth callback from Spotify and have problems with the # in my URL.
routes.js
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
...
when('/callback', {
templateUrl: 'views/callback.html',
controller: 'CallbackCtrl'
})
...
}]);
So to access that route the URL is e. g. http://test.com/#/callback
For the spotify endpoint the redirect_uri has to be url-encoded:
https://accounts.spotify.com/authorize/?client_id=...&response_type=code&redirect_uri=http%3A%2F%2Ftest.com%2F%23%2Fcallback&scope=user-read-private%20user-read-email&state=profile%2Factivity
The redirect from spotify:
http://test.com/%23/callback?code=..&state=profile%2Factivity
Which results in a 404
I know there are some workarounds like using the / route or enabling html5mode to get rid of the # but I hope there is a true solution for this.
Well your situation is not that awkward at all.
Since you can't control the way that spotify's redirect after OAuth works, it leaves you with two options:
1) Create a URL Path for example http://test.com/redirect_uri/?code=.... which will automatically redirect the user to the webapp in the state of logged in.
This method is not a good practice, unless you really know exactly what you are doing. The major problem here is security. Unless you add really good Mechanism to the redirection page.
2) Easier, and actually better in all aspects:
$locationProvider.html5Mode(true);
A small introduction on this:
Why does this remove the #? Because when HTML5 mode is on, it will use history to refer to native paths in your app.
But hold on this is not the only thing you have to do:
You have to redirect all request to go through the main page normally index.html.
I use to do this with .htaccess, But since of AngularJS 1.3 I know there is another method with adding meta tag of <base href=/base/path/of/app/directory">. Usually <base href="/">
But I still prefer .htacces rewriterule or w/e webserver you are using accordingly.
It looks like you are going to implement the Authorization Code flow client-side, exposing the secret key you were provided when you register your app. This is wrong, since someone might generate tokens on behalf of your application using the client id and secret key.
A better approach is to either use Implicit Grant (in example how it is done on https://github.com/possan/webapi-player-example) or implement the token exchange server-side and pass the token to your AngularJS webapp.
Check out this article on Scotch.io for "pretty URL's" that should fix this issue.
You will have to set html5Mode to true:
// Remember to inject $locationProvider
$locationProvider.html5Mode(true);
Then, include a base in the of your html file:
<base href="/">
This will let you navigate the webpage using relative links.
The article I mentioned also goes into fallbacks for older browsers.

User profile info getting reset after each page refresh (using Hello.js)

I'm using Hello.js in my AngularJS application to let users authenticate with Facebook. Once the user is logged in and I get the user information from Facebook, I use the json and get the user object from my own database and store it in the root scope, so that various areas in my site can access the user's profile info (for example in the header where I display the logged in user's name).
Here's the service that handles the authentication stuff
angular.module('myApp')
.factory('userService', function($rootScope, $location) {
// Hello.js Functions
hello.init({
facebook : '1234567891234545'
});
var service = {
isLoggedIn: function() {
return $rootScope.loggedInUser != null;
},
login: function() {
hello('facebook').login( function() {
hello('facebook').api('/me').success(function(json) {
$rootScope.loggedInUser = getUserFromMyOwnAPI(json.id);
$rootScope.$apply(function() {
$location.path('/');
});
});
});
},
logout: function() {
hello('facebook').logout( function() {
$rootScope.loggedInUser = null;
$location.path('/');
});
},
loggedInUser: function(){
return $rootScope.loggedInUser;
}
}
return service;
})
The issue I'm having is that every time I refresh the page, I lose the profile info. Makes sense because $rootScope.loggedInUser which stores the user data (based on the json I got back from Facebook) would get reset after a page refresh.
How should I handle this? Should I be putting the user data in localStorage instead of the rootScope? Or should I somehow be leveraging hello('facebook').api('/me') each time I want to reference the user's profile info?
I noticed that hello.js already stores something in localStorage:
key: hello
{"facebook":{"state":"","access_token":"blahblahblah","expires_in":6776,"https":"1","client_id":"12345","network":"facebook","display":"none","redirect_uri":"http://adodson.com/hello.js/redirect.html","scope":"basic","expires":1412632794.806}}
So I 'm wondering if I would be duplicating the effort by adding the user object to localStorage.
The answer to this question is subjective and could be argued different ways. However, based on your question and comment, my opinion is that retaining (non-sensitive) user profile information in local storage would be a good option to provide an uninterrupted user experience.
Never store the user information including but not limited social network info inside the localStorage, cookie, and/or other unsecured mechanisms. Even if you need to make a compromise on a not so critical information, then use memory (like scope variables). You also have to account for complexities arising on storing user info in localStorage such as when user logs out of the social network. Now, session tracking is as old of WWW itself. How to track the sessions? There are countless articles discussing the pro and cons of Cookies, Json Web Tokens, Session State in server side, etc. My personal opinion is to store the most of the user info in server side and link the current user to that session using a session ID stored in any possible medium like Cookie, Query Param, localStorage etc. Thats only useful if you have a backend and your OAuth provides you a token. I dont see anywhere in hello.js that it provides you a token. So given that you shouldnt store any client side user info in browser, and hello.js doesnt provide you with a token to reuse in subsequent calls my advice to you is to login the user every single time.
about your code:
As Adin and DanArl already stated, you can implement the process of the user's session tracking in many different ways - preferably server side, identified via some kind of identifier stored in a session cookie.
Concerning your actual code, you may have a look at jshint:
Three warnings
10 Use '!==' to compare with 'null'.
31 Missing semicolon.
34 Missing semicolon.
Three undefined variables
1 angular
4 hello
13 hello
14 hello
23 hello
15 getUserFromMyOwnAPI
You should inject 'hello' correctly, by passing 'hello' to your 'userService'.
(have a look at: https://docs.angularjs.org/guide/di if you want more information about dependency injection in AngularJS)
about your actual problem:
After you have received the token - from your prefered way of storing it - you should be able to inspect and validate the token via:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app-token-or-admin-token}
Source: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.1#checktoken
Then you may have a shot at passing this information to helljs (i'm used to this library)

Categories

Resources