I am a beginner in web development.
I create a project only in HTML, CSS, and Javascript.
My task is to create the login page and main page, but the user can access the main page only when he is logged.
In the backend are database connector scrip, a login script, and script which checking user is logged.
Before the user opens the main page script creates a request and gets a response from the script in this format:
{
"logged": true,
"uid": 123456
}
I parse JSON and if logged is false I redirect to the login page using window.location.replace().
Is this approach prevent from open the main page when the user is not logged?
I am asking because clients can modify Javascript files in a web browser.
I know that it is easier to create this in PHP using the location header and it can't be modified by the client, but I can't make it in this way.
I am asking because clients can modify Javascript files in a web browser.
Not really. But yes, a check such as what you describe is easily circumvented client-side.
The rule is this: Anything that should not be visible to the user if they aren't authorized and authenticated must not be sent to the client at all unless that authentication has been provided. So the request for the "main page" from the server must be allowed or disallowed by the server, and served non-cacheable.
Usually the page itself isn't all that protected, but the information you show on the page is. E.g., the page is the scaffold and layout and such, but the protected information it shows is provided using ajax or similar, and only when the user has been authenticated.
Related
I have Single Page Application, browser only webapp (javascript, no server side).
The user interacts with the application and sets some variables.
Far after the creation of the main index.html page, when the user wants to upload a file, he needs to authenticate with an external service using oauth2 (using "token / implicit grant").
Once authenticated, the authentication service responds with a redirect, possibly to another page (page2).
What should the page2 do to continue the flow of the program?
Should it redirect back to the original main page (this time, with the access token)?
If so, wouldn't this reload the main page and reset the application and the variables that were set?
Thanks,
Avner
EDIT
Ricardo,
I don't use a specific web platform, just plain javascript.
#charlietfl
I found a general example here that does postMessage between 2 seperate windows and it works ok.
I'm straggling to customize it according to Ricardo's comments, i.e.
make the second window popup
set a separate HTML file or a "noop" route on your SPA as redirect URL (what is a noop route?)
poll for that URL in the popup
I found this example that create the popup in the main page (index.html), set the redirect, and poll in order to close the popup.
In my case I set the redirect URL to a new page (auth.html) that does postMessage with the access token back to the main page (index.html).
If the auth.html page is not openned in the browser, should I still expect to receive a message in the main page index.html ?
From what I read for postMessage to work both pages, index.html, auth.html should be opened in 2 separate tabs in the browser.
You can use a small popup, which will load the necessary oauth2 endpoint, setting a separate HTML file or a "noop" route on your SPA as redirect URL. You may then poll for that URL in the popup, so you know when to close it (user is done with oauth2 flow).
This strategy is used by libraries like vue-authenticate, react-oauth and satellizer.
Also, depending on the specific service your are trying to authenticate against, you can find official libraries and SDKs that will handle the oauth2 flow automatically.
Last but not least, you could also save the current state of you application in browser storage, redirect to the oauth2 endpoint, and point back to your app as redirect URL. When coming back to your app, the specific route should be able to restore the saved data and resume user experience, with the addition of the oauth2 tokens.
Application, lots of html/js => app.html
If a user is authenticated true OAuth/Google-Drive => Have access
Else its not a logged in user => No access
This could be done server side, but then a OAuth flow would need to be executed on server side and then client side? I could move everything server side but that seems to be a lot of on the app engine resources (eg getFile(), updateFile()) which could be avoided; only client is taking to his own drive right? cut the middle man out.
I my going the right way about this?
If I understand you correctly, yes, this is correct. You can write Google Drive apps completely in the browser.
Why don't you redirect to the actual html page with the GDrive calls after authentication ?
It would go like this : every user lands on the login.html page, which only handles the OAuth part. Once the the OAuth token is retrieved login.html redirects the user to the actual app.html.
More generally though, I cannot see any reason why you would want to hide the code from users who did not authenticate to Drive. Anyway, without an OAuth token this code is useless.
I'm building a Single Page Application, read that login page should not be on the same page. Should I have login as a separate html page, or can I have login also in the same page.
If I have login as a different page, depending on the first page that I load should have to redirect to the other in client side.
ie suppose I load the SPA first, and if the user is not logged in, I've to redirect to login page in client side. and suppose I load the login page first, and the user is already logged in, I've to redirect to SPA in client side.
What is the general solution for this problem?
I'd put login and verification in a separate page and then use ajax to make the calls.
User access index-file.
Index-file makes checks with server-side page to see if user is logged in or not.
Page displays content depending on if the json answer from the server-side page was true or false.
Then I'd do the same for logging in.
User provides login information
Checks with server-side file through ajax and json.
Page refreshes if succesful or throws error response if it's not.
The bottom line to my answer is that when creating single-page applications, ajax is the way to go. However, since you havent provided what language you're using, i'm unable to give you a more detailed answer.
Client side single page handling logins and content selection however is very bad practice and should be avoided all-together because of their lack of security (I cant stress this enough) since all elements will be available even to anonymous access and DOM manipulation will enable an unauthorized user to access restricted content. You'll have to use ajax to do backend serverside authorizations - as mentioned, as well as serverside code on the SPA that present different content depending on your authorization status.
The scenario you describe need to have server-side code for selecting what content to present and client-side code together with ajax for implementing features on the SPA.
What you CAN do however, is to - when for example pushing the login button - calling another file with ajax, remove the content of the wrapper div and append the ajax response to that div. Then you'll avoid client side redirections all together.
There are few questions with same name but none of them intended to ask what I have in my mind. So we initialize FB js sdk with only app id. It's easy to know other web site's app id by looking at their facebook initialization source code. One might think that it's possible that a hacker might try to initialize FB JS SDK with other's app id and try to get their user access tokens. But facebook doesn't allow such stuff. You have to load js sdk from the same domain you specified in the site url property in Facebook Developer Apps page. So the question is how do they know that the jsonp whatever calls coming from the right client? It's not safe to that checking in client side since people can copy and modifty the javascript as they wish. So it has to be server side checking. I can only think of "referer checking" but I feel it cannot be considered a safe way.
Well, I'm not sure so this is only speculation..
First of all, when making an http request the HTTP referer header is added, and so when you load the sdk the url from which you're making the request is added as a referer.
Facebook can check on their servers where the request was originated from and compare that to what they have for the app settings.
It's possible of course to modify this header when making the request, which is why you don't get any error just by loading the sdk for an app if you're in the wrong domain.
The error will only occur when you try to interact with the sdk, for example trying to execute the FB.login method will open the auth dialog pop-up which will show the following error message:
An error occurred. Please try again later.
If you check the url of this auth dialog (which the sdk constructs) you'll notice these two query string parameters:
domain=THE_DOMAIN_OF_THE_PAGE
redirect_uri=FACEBOOK_URL which will contain origin, domain and relation=opener
What (probably) happens is that facebook checks the domain against the app settings, if it's ok it presents the user with the auth dialog, when he finished the process he is redirected to the redirect_uri.
Since the redirect_uri opens in the pop-up it can only communicate with it's opener if they are both in the same domain, a facebook domain which no one can have on his page other than pages served from facebook.
When the sdk loads it adds an iframe into the fb-root container which loads a facebook js which is loaded from the same domain as the redirect_uri, because of that the pop-up window can communicate back with the iframe and inform it with the auth response.
After the iframe got the response, the pop-up closes and the iframe informs the loaded sdk in the main page of the response.
I'm not sure which technique they use for that communication, but you can easy find more info about that by googling "cross domain iframe communication".
That's how I see it, but I can't be sure.
You can check the code for the js sdk # github if you want to really know what's going on.
According to the Facebook API documentation, most of the work is handled through javascript.
That means that all the processing is done, and then the front end checks if the user is connected to Facebook/authorized. right?
My question is:
Suppose a user goes to my site for the first time ever.
He clicks on "facebook connect". The javascript verifies him as authentic, and it "redirects" to another page on my server. From then on, how do I know that the user is actually authenticated to my website, since everything is done on frontend?
I think this is correct, but aren't there some security issues..:
-After user clicks Login, Facebook redirects to a page on my site. AND they also create a cookie with a specific "Facebook ID" that is retrieved only from this user. My backened will "read" the cookie and grab that ID...and then associate it to my userID.
If that is correct...then it doesn't make sense. What if people steal other people's "facebook ID" and then forge the cookie? And then my backend sees the cookie and thinks it's the real user...?
Am I confused? If I am confused, please help me re-organize and tell me how it's like.
Facebook Connect uses a clever (or insane, depending on your point of view) hack to achieve cross-site communication between your site and Facebook's authentication system from within the browser.
The way it works is as follows:
Your site includes a very simple static HTML file, known as the cross-domain communications channel. This file is called xd_receiver.htm in the FB docs, but it can be named anything you like.
Your site's login page includes a reference to the Javascript library hosted on Facebook's server.
When a user logs in via the "Connect" button, it calls a function in Facebook's JS API which pops up a login dialog. This login box has an invisible iframe in which the cross-domain communications file is loaded.
The user fills out the form and submits it, posting the form to Facebook.
Facebook checks the login. If it's successful, it communicates this to your site. Here's where that cross-domain stuff comes in:
Because of cross-domain security policies, Facebook's login window can not inspect the DOM tree for documents hosted on your server. But the login window can update the src element of any iframe within it, and this is used to communicate with the cross-domain communications file hosted on your page.
When the cross-domain communications file receives a communication indicating that the login was successful, it uses Javascript to set some cookies containing the user's ID and session. Since this file lives on your server, those cookies have your domain and your backend can receive them.
Any further communication in Facebook's direction can be accomplished by inserting another nested iframe in the other iframe -- this second-level iframe lives on Facebook's server instead of yours.
The cookies are secure (in theory) because the data is signed with the secret key that Facebook generated for you when you signed up for the developer program. The JS library uses your public key (the "API key") to validate the cookies.
Theoretically, Facebook's Javascript library handles this all automatically once you've set everything up. In practice, I've found it doesn't always work exactly smoothly.
For a more detailed explanation of the mechanics of cross-domain communication using iframes, see this article from MSDN.
Please someone correct me if I'm wrong - as I am also trying to figure all this stuff out myself. My understanding with the security of the cookies is that there is also a cookie which is a special signature cookie. This cookie is created by combining the data of the other cookies, adding your application secret that only you and FB know, and the result MD5-Hashed. You can then test this hash server-side, which could not easily be duplicated by a hacker, to make sure the data can be trusted as coming from FB.
A more charming explaination can be found here - scroll about halfway down the page.
Same issues here, and I think Scott is closer to the solution.
Also Im using "http://developers.facebook.com/docs/?u=facebook.jslib-alpha.FB.init" there open source js framework. So things are a little different.
For me, via the opensource js framework, facebook provides and sets a session on my site with a signature. So what I am thinking is to recreate that signature on my side. - if they both match then the user is who he says he is.
So basically if a user wanted to save something to my database, grab the session signature set up by facebook and recreate that signature with php and validate it against the one facebook gave me?
if($_SESSION['facebookSignature'] == reGeneratedSignature){
// save to database
}else{
// go away I don't trust you
}
But how do you regenerate that signature? preferably without making more calls to Facebook?