I created a login page on my mobile app using a node js file to test the credentials. If the credentials are correct you get to the homepage, but It doesn’t remember the logged-in user, so every time you clean the RAM you have to login again.
I'm trying to save the token I get back from the backend in the device using #ionic/storage, but that's how far I can go on the logic and code. I don't really know what to do with the token. Some explaining of the logic could help a lot, or some code, or a link. I would really appreciate any help I can get!
I’m using Ionic Angular [5] and Capacitor.
My code if needed:
.ts file
senduserdata(){
var dataToSend = {
username:this.Username,
password:this.Password,
usertype:this.getSelectedSubject,
}
var url = 'http://localhost:3000/login';
this.http.post(url,{data:JSON.stringify(dataToSend)},{responseType: 'text'}).subscribe(
(data)=>{
let decoded = helper.decodeToken(data);
console.log('Decoded: ', decoded);
//the code to save it in storage
this.storage.set('loggedToken', decoded);
if(decoded.usertype === "Customer")
{
alert('Hello Customer')
}
else if(decoded.usertype === "Staff")
{
alert('Hello Staff')
}
}
)
}
node js file
//Login
app.post('/login', function (_req, res) {
var data = JSON.parse(_req.body.data);
var username = data.username;
var password = data.password;
var usertype = data.usertype;
mysqlConnection.connect(function () {
if(usertype ==="Customer"){
var query = "SELECT * from " + usertype + " Where Username = '" + username + "' And Password = '" + sha1(password) + "'";
}
else{
var query = "SELECT * from Staff Where Username = '" + username + "' And Password = '" + password + "'";
}
mysqlConnection.query(query, function (err, results, _fields) {
if (err) {
res.send(err);
}
else {
if (results.length > 0 && usertype === "Customer") {
if(results[0].Subscription === "True"){
passs = sha1(password)
const token = jwt.sign({username, passs, usertype}, 'my_secret_key_customer');
console.log(token);
res.send(token);
}
else{
console.log("Email not verified!");
res.send('Email not verified! Check your email for the verification email!');
}
}
else if (results.length > 0 && usertype === "Staff") {
passs = sha1(password)
const token1 = jwt.sign({username, passs, usertype}, 'my_secret_key_staff');
console.log(token1);
res.send(token1);
}
else {
console.log("The password or username is incorrect!");
res.send('The Password or Username is incorrect!');
}
}
})
})
});
you can use that decoded value that you saved in ionic storage as and 'id' of the user (you can read about JWT that is a way of doing this that is a standard) so you can use that value when making new requests to your node-js server so you can know which user is sending the request (it is the equivalent of been logged in on REST). you can also use the value to change which is the default page of the app when you are logged in (login page when not logged in and home page when logged in for example.)
You need to setup authentication Guards to restrict pages based on storage and also add HTTP intercept to override HTTP header and passing the JWT token to backend on each and every API call's.
JWT is a JSON based web token to securely transfer data between Backend and JSON Objects. It may contain USER ID and other some secure information. You can pass your customized data using JWT.
Related
I have been putting together a website and i've been using the latest firebase script and everything.
When I request for a custom user attribute that has been created it says it's 'undefined'.
CustomAttributes:
points
ownedavatars
Code:
SignUp
var user = firebase.auth().currentUser;
user.updateProfile({
displayName: //username,
photoURL: //icon,
points: 0,
ownedavatars: "default"
}).then(function() {
user.sendEmailVerification().then(function() {
//it would save email and password and then redirect here
}).catch(function(error) {
console.log(error.message);
});
}).catch(function(error) {
console.log(error.message);
});
Login
var listofavatars;
firebase.auth().signInWithEmailAndPassword(email, password).then(function() {
var user = firebase.auth().currentUser;
if (user != null) {
document.getElementById("user").innerHTML = user.displayName;
if (user.points == undefined) {
document.getElementById("points").innerHTML = "0p";
} else {
document.getElementById("points").innerHTML = user.points + "p";
}
listofavatars = user.ownedavatars;
if (user.photoURL == "default") {
document.getElementById("avatar").src = //would pull default;
} else {
document.getElementById("avatar").src = //would pull any other icon saved;
}
}
}).catch(function(error) {
alert(error.message + " Code:" + error.code);
});
You can't use updateProfile to save arbitrary custom user variables. This API only currently supports photoURL and displayName`. To save other user data, you have to use a separate database to do so. You can use Firebase realtime database or Firestore to do so. Here is an example how to save user specific data securely: https://firebase.google.com/docs/database/security/user-security
If you need to save user specific data for role based access control, you can use the Firebase Admin SDK to set custom user attributes:
https://firebase.google.com/docs/auth/admin/custom-claims
However, it is highly recommended that this custom user data is to be used for access control. For other data, use a dedicated database as described above.
I am trying to build a basic Auth using post
app.post("/api/auth",function(req,resp)
{
var username = req.body.username||req.param('username');
var password = req.body.password||req.param('password');
log("Performing Log Check");
log(username + " "+password);
var sent ={};
sent.status =false;
sent.authenticated = false;
var query = {}
query.sql= "SELECT * FROM voix_auth";
query.timeout= 4000; // 40s
connection.query(query, function (error, rows, fields)
{
if(!error)
{
var i=0;
while(i!=rows.length)
{
if(rows[i].username == username && rows[i].password == password)
{
log(rows);
sent.status = true;
sent.authenticated = true;
sent.token = tokenData;
log(sent);
break;
}
i+=1;
}
resp.send(sent);
} //Error Ends
else
{
log("Error Occured");
}
}); //connection Query
log(sent);
resp.send(sent);
});
The issue here is that I get Cannot set header After They are Sent.
So when I remove resp.send() this error is gone.
But if the response I get is always false even though the user is Authenticated.
Please help.
You cant send out multiple responses.
Things to change
Change query to something like select ONLY_STUFF_YOU_NEED from table where username & passwords match. Take care of sql injection.
Wrap the query in a function that returns back a valid user object ONLY if auth matches. Move it outside the controller. Example + shameless plug - https://github.com/swarajgiri/express-bootstrap/tree/master/core
After auth is done, send the response using res.send
I'm trying to get started with firebase and now with the security part of it. I'm trying to keep it as simple as possible in order to get started, using guides and code snippets from the Firebase website.
In order to keep it simple I have a webpage containing a password (id "Code") and user input field (id "Door"). How do I check if the password entered in field "Code" is equal to the password that is already stored in node https://mydatabase.firebaseio.com/loapp_users/BAAJ/password, BAAJ being a userid of one of the users stored in node loapp_users, all with a child node "password"?
The code below doesn't seem to do the trick.
$(document).ready(function(){
// Monitoring User Authentication State
// Use the onAuth() method to listen for changes in user authentication state
// Create a callback which logs the current auth state
function authDataCallback(authData) {
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
} else {
console.log("User is logged out");
}
}
// Register the callback to be fired every time auth state changes
var ref = new Firebase("https://mydatabase.firebaseio.com");
ref.onAuth(authDataCallback);
$("#logout").click(
function logout() {
ref.unauth();
ref.offAuth(authDataCallback);
}
);
// LOGIN
// The code to authenticate a user varies by provider and transport method, but they all have similar signatures and
// accept a callback function. Use it to handle errors and process the results of a successful login.
// Create a callback to handle the result of the authentication
function authHandler(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
};
$("#login").click(
function() {
var usersRef = new Firebase("https://mydatabase.firebaseio.com/loapp_users");
// Authenticate users with a custom Firebase token
var _user = $("#Door").val();
var _level = "docent";
var _password = $("#Code").val();
var userRef = usersRef.child(_user);
// Attach an asynchronous callback to read the data at our user reference
userRef.on("value", function(snapshot) {
console.log(snapshot.val());
if (snapshot.val().child("password").text() == _password) {
ref.authWithCustomToken("eyJ0e....etc...mlhdCI6MTQyOTM4Mzc0M30.Vn1QF7cRC6nml8HB9NAzpQXJgq5lDrAie-zIHxtOmFk", authHandler);
} else {
console.log("Gebruikersnaam en code komen niet overeen")
}
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}
);
});
snapshot.val().child("password").text()
should instead be:
snaphot.val().password
Then it works.
I've got a form which is used to update a user's information, both in the Firebase JSON tree and the seperate database which holds the email + password combination for the users. Whenever you want to update either the email or password, you need to provide an email + password combination for it to work.
However, when you only want to update the JSON tree you can do it without a password. My form requires you to enter your current password before anything can happen, but if you type in the wrong password it will still update the display name of the user.
So my question is, is there a way that I can require the correct password before actually updating anything in the database?
The code in my controller:
//If the user has entered a new display name
if (sharedInfo.getUser().displayName !== $scope.user.displayName) {
var isNameChanged = userLogic.changeDisplayName($scope.user);
isNameChanged.then(function(isSuccessful) {
if (isSuccessful === true) {
$scope.isSuccessful = true;
}
else {
$scope.error = 'Update failed';
}
});
}
Function in my service:
changeDisplayName: function(user) {
//Get the user ID
var userData = sharedInfo.getAuthState();
return fbRef.getSyncedReference('users/' + userData.uid).$update({displayName: user.displayName}).then(function() {
return true;
}, function(error) {
return false;
});
}
I have been struggling with this problem all day.
I am developing a Windows 8 app using JavaScript and HTML5. I need to restrict some functionality on the app depending of the active directory group where an user account is assigned.
The question is: how I can check if a user account belongs to a Active Directory group?
I have tried using Windows.System.UserProfile.UserInformation and Windows.Security.Credentials.UI.CredentialPicker, but none of them returns either a way to test if a user account belongs to a group, or the group where the user account is assigned.
Thanks in advance for your help.
I found a solution to perform this, which was the one I implemented, and it works. You can create a web service that validates the credentials against Active Directory, where you pass the domain, username and password, then call it from the app using WinJS.xhr. To ask for the credentials, you can use the CredentialPicker control, which returns, the domain, username, and password entered by the user.
Here is the code:
Web Service Code:
ValidateUserResult vur = new ValidateUserResult();
try
{
using (PrincipalContext context =
new PrincipalContext(ContextType.Domain, domain))
{
vur.UserCredentialsAreValid = context
.ValidateCredentials(username, password);
if (vur.UserCredentialsAreValid)
{
vur.ProcessMessageText = "Ok";
vur.ProcessMessageCode = 0;
}
else
{
vur.ProcessMessageText =
"Credenciales invalidas";
vur.ProcessMessageCode = -1;
}
}
}
catch (Exception ex)
{
vur.UserCredentialsAreValid = false;
vur.ProcessMessageText = ex.Message;
vur.ProcessMessageCode = ex.HResult;
}
return vur;
Windows 8 App:
WinJS.xhr({
type: "get"
, url: {Web Service Url}
+ "/json/{Web Service Method Name}?domain="
+ domain + "&username=" + username
+ "&password=" + password
}).then(
function (result) {
if (result.status === 200) {
// Place code here.
}
},
function (error) {
// If an error occurs, manage here
});