AngularJS + PHP Login authentication - javascript

I'm building a WebApp where i have a login page and also some user restrictions.
I have my app running perfect but now I'm stuck in the login process.
The WebApp is based on AngularJs, PHP and a database with MYSQL.
Also, I'm asking this because i didn't found any good answer or work process on the first steps of the login process. Also keep in mind I'm not an AngularJs advanced user, I'm still learning, so sorry if I'm making somethins stupid.
What i have:
Right now I have a simple login system (working) using only PHP, like this:
index.php
<?php session_start();
include ('dist/php/config.php');
if(isset($_GET['out'])){
session_destroy();
back("#");
}
if((!empty($_POST['user'])) && (!empty($_POST['password']))){
$p = ['user'=>$_POST['user'], 'password'=>$_POST['password']];
$r = sql("select * from users where user= :user and password = :password",$p);
if($r != 0){
foreach($r as $ln){
$_SESSION['loggedin']=$ln['name_user'];
}
} else {
$msg = "<div class='login_fb'><p>User or password incorrect</p></div>";
}
}
if(!empty($_SESSION['loggedin'])){
include "system.php";
} else { ?>
<head>
<meta charset="UTF-8" />
[... rest of head ...]
</head>
<body>
[... rest of body with login form ...]
</body>
<?php } ?>
My routing system is controlled with AngularJs ui-router.
The problem this system (at least i don't know how to do it) is to keep the user data reusable even after the page refresh.
My objective
What i want is:
Login into the WebApp;
Store user data to be used in all pages; For example, it's name or it's ID;
Be able to refresh the page and don't lose the logged state;
Control the user access based on it's power level (master, admin, user, guest);
Secure Login system;
Prevent users to access a further page when changing the URL manually. For example: Typing webapp.com/#/order and with this they jump the login process;
I've alreay found some examples, but they are way to complex (i mean, lack of explanation or plain code), or have some of these failures. I also found this great answer here but it already start the explanation with user logged in.
Also, i saw some reference to use $cookieStore (or just $cookie, since it's deprecated) like this:
app.run(['loginService', function(loginService){
var username = $cookieStore.get('username');
var password = $cookieStore.get('password');
loginService.login(username, password);
}]);
But is it ok to use this code? Is it safe? Because we'll have to handle the password value.
What i want to know
So, with this is mind, what i want to know is:
Is it ok, recommended or is there a better option to handle the login process than the one I'm using at the momment?
How can i prevent the users to access the WebApp without the login process?
How can i store the user data to control it's access to restricted areas or to just simple show a message with his name?
How to keep the user logged in even after the refresh?
If it's okay to stay using the same login system I'm using now, how can i keep the user information reusable trought all the other pages and also keep it reusable after a page refresh?
Hope you guys can help me.

Related

Conceal URL in javascript code ( URL generated by PHP )

I am looking for a solution to the following:
I have a piece of JS code, that performs a redirection to a URL that is constructed with PHP, and that redirection is only done when the user presses a button on a confirmation dialog.
The code is, as follows:
function one() {
window.location.replace("<?php
if($new_redir == "1") {
echo "$new_second_redirect_URL/?token=$hash";
}
else {
echo "$second_redirect_URL/?token=$hash";
}
?>");
}
It works perfectly fine. What I wanna do is conceal the URL that is displayed in the source code when a user opens the page.
What would be the best way to do that?
You're thinking too much into this to be honest.
If they want to avoid the confirmation screen and get the URL from the source, there's not really much you could do.
The best really is possibly performing an AJAX request on confirmation and getting a CSRF token based URL from the response and using that, but that could end up being overkill as well.
You could also make it into an actual <form></form> form with a few hidden fields (again, such as a CSRF token), and perform the post validation onclick. If it a success - redirect them.
UPDATE:
Use robots.txt to stop bots
Build the QS with JS to stop most bots, something like:
var csrftoken='XJIWHEOU324uipHFOFUHR';
var url="http://url.com/page.php?token=";
url=url+csrftoken;
What you could also do, is something like us actually, although for your use case it could be too much.
Log every single page load into the DB, and check if if they're a first time visitor to the page after confirmation.
AJAX call (jQuery example):
$.post( "url_to_backend_page_to_get_url", {hasSubmittedForm:"true"}, function( data ) {
window.location.href = data;
});

Ajax post request vulnerability

I'm trying to record user's clicks on a specific iFrame in a div containing an ad, in order to block problematic IP addresses, thus preventing those who are trying to spam the ad, from being able to click it again. In each click made by the user, a record will be inserted into a table in mySQL database which includes:
IP address
Clicks counter
Unix timestamp
Each user/IP address has a privilege to click the ad 3 times in 24 hours.
For detecting each click on the iFrame ad, I used iframeTracker-jquery class and implemented a JavaScript code as follow:
index.php:
<?php include 'AdProtection.php'; ?>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/jquery.iframetracker.js"></script>
<script>
jQuery(document).ready(function($) {
$('.iframetrack iframe').iframeTracker({
blurCallback: function() {
console.log("Click has been detected!");
$.ajax({
type: "POST",
url: "update.php"
);
}
});
});
</script>
</head>
<body>
<div class="iframetrack" id="adsense_frame">
<?php //Returns true when a user 's IP address isn't currently blocked by checking in Database. if(AdProtection::protectAd()) echo '<iframe width="728" height="90" src="js/demo/sample-iframe/red.html" frameborder="0" allowtransparency="true" scrolling="no"></iframe>'; ?>
</div>
</body>
</html>
update.php:
<?php
function update($odb)
{
$sql=$odb->prepare('INSERT INTO system (ip, clicks, timestamp) VALUES(:ip, clicks+1, :timestamp) ON DUPLICATE KEY UPDATE clicks = clicks+1, timestamp = :timestamp');
$sql->execute(array(':ip' => ip2long($_SERVER['REMOTE_ADDR']),':timestamp' => time()));
}
//PDO Connection
include ( "db.php");
$sql=$odb->prepare('SELECT clicks, timestamp FROM system WHERE ip= :ip');
$sql->execute(array(':ip' => ip2long($_SERVER['REMOTE_ADDR'])));
$data = $sql->fetch();
if($data != null)
{
if($data['clicks'] % 3 == 0)
{
if(($data['timestamp'] + (24 * 60 * 60)) < time())
update($odb);
else
//User is currently blocked.
}
else
update($odb);
}
else
update($odb);
There are 2 crucial problems when implementing this JavaScript code / jQuery POST request:
The code can be manipulated/modified by an individual since JavaScript is a client-side language.
A spam can be made on the update.php file.
How can I deal with these problems ?
Do the checks server-side. Always.
You have neither control nor reliable knowledge about the client, so with anything sensitive, don't trust it.
Ultimately, a user may just download the source code of an open-source browser and modify it as (s)he wishes.
Disabling things client-side is a nice plus if it indicates that functionality is not available, and it might save you and your users some time and bandwidth, but there are gonna be those who try to circumvent it, and for those you need to be prepared.
Disabling things server-side means just denying execution, i.e. just put an exit; after your comment //User is currently blocked., that should do it.
For your second question: yes, the update.php might get spammed, but so might any other PHP script.
Every reasonable web server I know has some way of limiting the amount of requests a client can make in a certain amount of time.
Lighttpd has a native mod_evasive, nginx has HttpLimitReqModule and for Apache there's a number of things, see this SO answer.
If the spamming exceeds the capabilities of your web server, it's time to look into DDos protection.
Js code may be manipulated by anyone as its client side all what you can do is to minimalise risk of your code to be potentially disabled by other script in order to do it write your js to use only private methods and variables in a self-executing function. So the code will be not visible in global namespace, you may also need to copy definitions of globally available objects (like document or getElementById) as they may change them and not your code itself. After that obfuscate code and minify it.
For PHP you will probably need to implement some kind of authentication to work in pair with your js script as this is nothing more than securing any request for access so maybe IP or session validation. Yo may also implement some other server side mechanisms in order to prevent this script from being accessed by certain IP adresses.
You may also decide to not display iframe at all for certain ip addresses or by device fingerprint http://en.wikipedia.org/wiki/Device_fingerprint which will not depend on client side logic, this will probably make it more secure than solution proposed by you.

Is it possible to delete an entire Webpage when the user navigates away?

If the user navigates off the webpage, is it possible to execute a php script?
I know that Javascript can be executed..
$(window).bind('beforeunload', function(){
return 'DataTest';
});
Cookies might work, but I am not sure how a listener could track an expired cookie, and then delete the correct webpage.
A sample file system is like this:
user0814HIFA9032RHBFAP3RU.php
user9IB83BFI19Y298RYBFWOF.php
index.php
listener.py
data.txt
Typically, to create the website, php writes to the data.txt and the Python listener picks up this change, and creates the file (user[numbers]). As you might think, these files stack up overtime and they need to be deleted.
The http protocol is stateless, therefore users simply can not "navigate away".
The browser requires a page, the server returns it, and the communication stops.
The server doesn't have reliable methods to know what the client will do with that page.
Disclaimer: I'm not sure, as Fox pointed out, that this is the right way to go in your case. I actuallly upvoted Fox's answer.
However, if you absolutely need to delete each page right after the user left it, use this:
$(window).bind('beforeunload', function() {
$.ajax('yourscript.php?currentUser=0814HIFA9032RHBFAP3RU');
});
Then in yourscript.php, put something like the following:
<?php
// load your userId (for example, with $_SESSION, but do what you want here)
$actualUser = $_SESSION['userId'];
// checks if the requested id to delete fits your actual current user's id
if (isset($_GET['currentUser'] && $_GET['currentUser'] == $actualUser)
{
$user = $_GET['currentUser'];
$file = 'user'.$user.'.php';
unlink($file);
}

Ajax Login that refresh only the logged div

Using Zoo Visitor ajax login or Ajax Auth, i manage well the ajax login witn EE.
When the user is logged, how to refresh only the div that contains: welcome user you are logged.
<div class="Welcome"><span>{username}</span> Logout</div><br />
Here is the Zoo Visitor Ajax login script:
$(document).ready(function(){
$('#loginForm').ajaxForm({
dataType: 'json',
success: function(data) {
if (data.success) {
alert('You are now logged in. You can add additional actions in the js script.');
} else {
alert('Failed with the following errors: '+data.errors.login);
}
}
});
});
I guess i have to insert a javascript code inside:
alert('You are now logged in. You can add additional actions in the js script.');
I'm still learning javascript, using
setInterval(function(){
document.getElementById('info').innerHTML =
It's a good method??Does someone has some tips??
It is possible to use a Expression Engine function??
thanks,
Stéphane
Assuming your <div class="Welcome">...</div> already exists on the page you would replace
alert('You are now logged in. You can add additional actions in the js script.');
With
$('div.Welcome').html('<span>Welcome...</span> Logout');
However, note that I removed {username}. When the user visits the page while logged out they do not have a username. When they log in via AJAX the page is not refreshed, therefore the username still remains on the server side. Zoo Visitor does not return any member data with it, either.
It might be better for you to just use a regular log in process than use AJAX if you're trying to do app-like stuff.
If you still want to stick to JavaScript for this then one thing you could do is create a template that returns the data via JSON, e.g.
{exp:http_header content_type="application/json"}
{ "username": "{username}" }
(Note the use of the http_header plugin.)
Right after a successful login you would use AJAX to check that template, then confirm the results. If username has a length then you know the person is logged in and you can update your Welcome div.
Or... you may want to try logging in via Open API by Ben Croker. Apparently its authentication returns the member data you're looking for, see http://docs.eeopenapi.apiary.io/#authentication

global variables doesn't change value in Javascript

My project is composed by 2 html pages:
index.html, which contains the login and the registration form.
user_logged.html, which contains all the features of a logged-in user.
Now, what I want to do is a control if the user is really logged in, to avoid the case where a user paste a url in the browser and can see the pages of another user.
hours as now, if a user paste this url in the browser:
www.user_loggato.html?user=x#profile
is as if logged in as user x and this is not nice.
My html pages both use js files that contains scripts.
I decided to create a global variable called logged inizialized to false and change the variable to true when the login is succesful.
The problem is that the variable, remains false.
here is the code:
var logged=false; (write in the file a.js)
while in the file b.js I have:
function login() {
//if succesfull
logged=true;
window.location.href = "user_loggato.html?user="+ JSON.parse(str).username + #profilo";
Now with some alerts I found that my variable logged is always false. Why?
Javascript is not the way to go, as it runs on the client side. Even if there would be a way to share javascript variables between different requests, the user could manipulate them.
You have to take a server side technique for this (maybe PHP with sessions).
JS variables will reset on every submit/refresh. You could use sessionStorage or cookies for this purpose. For example:
Put this in your login form:
function login() {
window.sessionStorage[logged] = true;
window.location.href = "user_loggato.html?user="+ JSON.parse(str).username + #profilo";
}
And in your user_loggato.html, you can retrive it like:
function getLoginStatus() {
return window.sessionStorage['logged'];
}
Hope this helps.

Categories