Good Day,
I want to create a very basic app login hence I am looking for alternatives to OAuth, Token Auth etc. I just want a login page with a Username and Password. That's it, nothing else. Therefore, I decided to use Secure Storage with the thought process being.......a username and password is stored by a user initially. When the user opens the app in the future, they enter the same user name and password and hit 'Login'. So, this login checks the keychain to ensure the password is correct and then allows access to the app by opening a new window.
I modified the Secure Storage code to include a 'Login' Button however nothing happens when I hit Login. Therefore, I assume that the problem lies with the Login button. Can I be guided on how to fix this? Thank you. Below is the code:
import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import QtGraphicalEffects 1.0
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1
import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
//import Esri.ArcGISRuntime 100.1
import ArcGIS.AppFramework.SecureStorage 1.0
import "controls" as Controls
App {
id: app
width: 400
height: 750
function units(value) {
return AppFramework.displayScaleFactor * value
}
property real scaleFactor: AppFramework.displayScaleFactor
property int baseFontSize : app.info.propertyValue("baseFontSize", 15 * scaleFactor) + (isSmallScreen ? 0 : 3)
property bool isSmallScreen: (width || height) < units(400)
property string insertSuccessMessage: qsTr ("Inserted into Keychain")
property string removeSuccessMessage: qsTr ("Removed from Keychain")
property string failMessage:qsTr("Something Went Wrong")
property color successColor: Material.color(Material.Teal)
property color errorColor: Material.color(Material.DeepOrange)
Page {
anchors.fill: parent
header: ToolBar{
id:header
width: parent.width
height: 50 * scaleFactor
Material.background: "#8f499c"
Controls.HeaderBar{}
}
// sample starts here ------------------------------------------------------------------
contentItem: Rectangle {
anchors.top:header.bottom
ColumnLayout {
spacing: 5 * scaleFactor
anchors.horizontalCenter: parent.horizontalCenter
// Insert key in this text field
TextField {
id: username
placeholderText: "Username"
echoMode: passwordVisible.checked === true ? TextInput.Normal: TextInput.PasswordEchoOnEdit
Material.accent: "#8f499c"
Layout.topMargin: 100 * scaleFactor
Layout.fillHeight: true
Layout.fillWidth: true
}
// Insert value in this text field
TextField {
id: password
echoMode: passwordVisible.checked === true ? TextInput.Normal: TestInput.PasswordEchoonEdit
placeholderText: "Enter password"
Material.accent: "#8f499c"
Layout.fillHeight: true
Layout.fillWidth: true
}
//Click on the button to store key and value in the keychain
Button {
id: saveButton
text: qsTr("Save Data to Keychain")
onClicked: {
SecureStorage.setValue(username.text, password.text)
}
}
Button {
id: loginButton
text: qsTr ("Login")
onClicked: {
if(password.text === true) {
var component = Qt.createComponent("Child.qml")
var window = component.createObject (root)
window.show ()
}
}
}
}
}
}
}
Giatri,
I would first check in the login button "OnClicked" that has the if statement, with console.log to see if it is running the code inside the if statement.
Thank you,
Erwin
Hi
I tried and nothing showed up. Any ideas on how I should move forward?
I switched the code up so that it can read
onClicked
password.text = true
When I run the code, nothing but this (the picture) happens.
Hi Giatri
Your issue appears to be just the if statement in your login button.
I suggest you console log the results of the following when you click the button:
(password.text === true)
(password.text == true)
(password.text === "true")
(password.text > "")
(password.text !== "")
etc etc and you will be able to understand what each returns.
I assume you are doing this just to test the button, because obviously there is little point in just checking if the password text exists. You will eventually want to retrieve the actual stored password value and compare the password.text to that. Purely for testing, you could probably use (password.text > "").
It should be noted too that what you are attempting should work, but is a very simplistic security approach and I'm not sure very many folk would recommend it. Is the device itself already secured by a passcode/login? In that case what you are proposing is fairly redundant because only the authorised person should be able to access the device in the first place. Depending on what OS you are using and where you store the data, other users could potentially access the data anyway. And you might need to consider things such as what to do if the user forgets their password?
Having said that, it should work!
Good luck.
Cheers,
-Paul
Thank you Paul for an indepth response I do want the login to be as simplistic as possible however there will be a few more options added to the login page (this is just for testing) and yes, there is the potential that the login may be redundant but it will be purposely done like that due to the nature of the app. No sensitive information will be ascertained from the app and information will be shared among each other so that is not a problem.
Also, you are totally right about retrieving the stored password and yes, I as I am testing it, I am understanding it more.
Hi,
I have adjusted the code and I know it is working since I have tested it randomly using:
onClicked: {
if (password.text !== SecureStorage.value(password.text)) {
loginButton.text =password.text
}
So I am not sure why when I use the code below, it is not working
var component = Qt.createComponent("Child.qml")
var window = component.createObject (root)
window.show ()
Hi Giatri
You might need to take a closer look at your Child.qml file, perhaps check what the .show() method actually does in that file. Also check it's size and anchoring as maybe it is displaying, just off screen or something random like that.
Also you are parenting the 'windows' variable to an object called 'root' but from a quick glance at your code above I couldn't see that object. Check what 'root' actually is.
And I'm not sure what your testing if statement is meant to do? What does SecureStorage.value(password.text) return? I'm unsure how password.text would ever equal SecureStorage.value(password.text).
if (password.text !== SecureStorage.value(password.text)) {
loginButton.text =password.text
}
cheers,
-Paul