please i want to know how to store the user input data in the registeration page then i pass it to login page and in login page i validate if the user write the right username and password or not(that already passed from registeration page)
here is my js code for registeration page:
<head>
<script>
//function to check if the passoword is matched
function checkpass() {
if (document.getElementById('psw').value ==
document.getElementById('psw-confirm').value) {
document.getElementById('message').style.color = 'green';
document.getElementById('message').innerHTML = 'Matched Passowrds';
} else {
document.getElementById('message').style.color = 'red';
document.getElementById('message').innerHTML = 'Those passwords didn’t match. Try again.';
}
}
//function to disable the submit button if the password is not matched
function check_pass() {
if (document.getElementById('psw').value ==
document.getElementById('psw-confirm').value) {
document.getElementById('submit').disabled = false;
} else {
document.getElementById('submit').disabled = true;
}
}
//function of cancel button
function goBack() {
window.history.back();
}
//function to only choose one gendre
function onlyOne(checkbox) {
var checkboxes = document.getElementsByName('check')
checkboxes.forEach((item) => {
if (item !== checkbox) item.checked = false
})
}
</script>
<link href="RegisterartinStyle.css" rel="stylesheet">
</head>
You can use sessionStorage to store temporary data like this...
sessionStorage.setItem('Username',username);
sessionStorage.setItem('Password',password);
To retreive the data from any of your pages...
var Username = sessionStorage.getItem('Username');
var Password = sessionStorage.getItem('Password');
Blow everything away...
sessionStorage.clear();
I have created a Python Azure Function and calling it via JS code hosted as an App Service on Azure.
I need to setup azure active directory authentication on this function.
I have configured azure active directory authentication in azure function app and azure app service and enabled CORS on both but still facing CORS issue
Access to XMLHttpRequest at 'https://login.windows.net' redirected from 'azure-function-url' from origin 'app-service-url' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Basically I want authentication for azure python function so that I can call it from AJAX request without exposing a token in app service?
Am I doing anything wrong?
Also is there a way I could return the logged in user's email-id with an azure function while using azure active directory authentication for that azure function? I can find a code sample in c#, below it is.
laimsPrincipal cp = ClaimsPrincipal.Current;
string welcome = string.Format("Welcome, {0} {1}!",
cp.FindFirst(ClaimTypes.GivenName).Value, `cp.FindFirst(ClaimTypes.Surname).Value);`
Now the issue is, I need to use Python to do this and I can't find a sample online. Can anyone please point me in the right direction? or maybe help translate this code.
This is a simple demo that calling an Azure function from html/JS code.
Step1: You should register an Azure AD application as your client so that you can use this app to login users and get tokens:
in this case , it will need Microsoft Graph API read user permission:
**Step2:**Create a python function with code below to test:
import logging
import base64
import azure.functions as func
import json
def main(req: func.HttpRequest) -> func.HttpResponse:
accessTokenPayLoad = req.headers.get("Authorization").replace("Bearer ","").split(".")[1]
data = base64.b64decode(accessTokenPayLoad + '==')
jsonObj = json.loads(data)
upn = jsonObj['upn']
return func.HttpResponse("hello, " + upn)
Basically, this function just read user's upn from access token to read user's email-id.
Step3 After you have created the function app, please enable CORS so that it could accept requests from static HTML:
Step4 The code below is the HTML/JS code sample that login users and get tokens to call the function:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Azure Function test</title>
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.4.4/js/msal.min.js"></script>
</head>
<body>
<div >
<button id="SignIn" onclick="signIn()">Sign in</button><br/>
<div id="WelcomeMessage"></div><br/>
<div id="functionResult"></div>
</div>
</body>
<script>
var clientAppID = "<your client app id>"
var tenantID = "<your tenant name/id>"
var functionURL = "<your function url>";
var demoScops = {
scopes:["user.read"]
}
var msalConfig = {
auth: {
clientId: clientAppID,
authority: "https://login.microsoftonline.com/" + tenantID
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
function signIn() {
myMSALObj.loginPopup(demoScops).then(function (loginResponse) {
console.log(loginResponse);
initPage();
}).catch(function (error) {
console.log(error);
});
}
function initPage(){
showWelcomeMessage();
getGraphAccessTokenToCallFunction()
}
function callFunction(accessToken){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
document.getElementById('functionResult').innerHTML = xmlHttp.responseText;
}
}
xmlHttp.open("GET", functionURL, true);
xmlHttp.setRequestHeader("Authorization", "Bearer " + accessToken);
xmlHttp.send(null);
}
function getGraphAccessTokenToCallFunction(){
myMSALObj.acquireTokenSilent(demoScops).then(function (tokenResponse) {
console.log(tokenResponse.accessToken);
callFunction(tokenResponse.accessToken);
}).catch(function (error) {
console.log(error);
})
}
function showWelcomeMessage() {
var divWelcome = document.getElementById('WelcomeMessage');
divWelcome.innerHTML = 'welcome! ' + myMSALObj.account.name ;
var loginbutton = document.getElementById('SignIn');
loginbutton.innerHTML = 'sign out';
loginbutton.setAttribute('onclick', 'signOut();');
}
function authRedirectCallBack(error, response) {
if (error) {
console.log(error);
}
else {
if (response.tokenType === "access_token") {
callMSGraph(graphConfig.graphEndpoint, response.accessToken, graphAPICallback);
} else {
console.log("token type is:" + response.tokenType);
}
}
}
function requiresInteraction(errorCode) {
if (!errorCode || !errorCode.length) {
return false;
}
return errorCode === "consent_required" ||
errorCode === "interaction_required" ||
errorCode === "login_required";
}
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
var msie11 = ua.indexOf('Trident/');
var msedge = ua.indexOf('Edge/');
var isIE = msie > 0 || msie11 > 0;
var isEdge = msedge > 0;
var loginType = isIE ? "REDIRECT" : "POPUP";
if (loginType === 'POPUP') {
if (myMSALObj.getAccount()) {
initPage()
}
}
else if (loginType === 'REDIRECT') {
document.getElementById("SignIn").onclick = function () {
myMSALObj.loginRedirect(requestObj);
};
if (myMSALObj.getAccount() && !myMSALObj.isCallback(window.location.hash)) {
initPage()
}
} else {
console.error('Please set a valid login type');
}
function signOut() {
window.localStorage.clear();
myMSALObj.logout();
}
</script>
</html>
Result:
I am creating an extension that has a button to download a file.
The file is created with the contents retrieved from the chrome's localStorage.
In panel.html I have the following code:
<!DOCTYPE html>
<html>
<body>
<button id="btnDownload">Download</button>
<script src="messaging.js"></script>
<script src="panel.js"></script>
</body>
</html>
Panel.js has the following event listener:
document.querySelector('#btnDownload').addEventListener('click', function() {
sendObjectToInspectedPage({action: "download"});
});
sendObjectToInspectedPage function is in messaging.js:
function sendObjectToInspectedPage(message) {
message.tabId = chrome.devtools.inspectedWindow.tabId;
chrome.extension.sendMessage(message);
}
On my background.js file I have the following code:
chrome.extension.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
if(message.tabId && message.content) {
if(message.action === 'download') {
var aFilePart = ['<a id="a"><b id="b">Hi :) !</b></a>'];
var blob = new Blob(aFilePart, {type : 'text/html'});
var url = URL.createObjectURL(blob);
chrome.downloads.download({
url: url
});
//Pass message to inspectedPage
} else {
chrome.tabs.sendMessage(message.tabId, message, sendResponse);
}
// This accepts messages from the inspectedPage and
// sends them to the panel
} else {
port.postMessage(message);
}
sendResponse(message);
}
// Listens to messages sent from the panel
chrome.extension.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
chrome.extension.onMessage.removeListener(extensionListener);
});
});
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
return true;
});
I want to generate the file with the content I pass and download the file to my computer when the download button is clicked but this is not working.
Am I doing something wrong? Is there something missing?
Thanks
You should use 'runtime' to send the message in messaging.js
chrome.runtime.sendMessage(message);
Also, in your background script this isn't required,
chrome.extension.onConnect.addListener()
Here is a simple example
function popupMsg(message) {
if (message.action == "download") {
//Do Something
} else {
//Something else
}
}
chrome.runtime.onMessage.addListener(popupMsg);
Here is the runtime documentation https://developer.chrome.com/apps/runtime
I am following this article on Social Logins with AngularJS and ASP.Net WebAPI (which is quite good):
ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app
Pretty much, the code works fine when you are running the social login through a desktop browser (i.e. Chrome, FF, IE, Edge). The social login opens in a new window (not tab) and you are able to use either your Google or Facebook account and once your are logged in through any of them, you are redirected to the callback page (authComplete.html), and the callback page has a JS file defined (authComplete.js) that would close the window and execute a command on the parent window.
the angularJS controller which calls the external login url and opens a popup window (not tab) on desktop browsers:
loginController.js
'use strict';
app.controller('loginController', ['$scope', '$location', 'authService', 'ngAuthSettings', function ($scope, $location, authService, ngAuthSettings) {
$scope.loginData = {
userName: "",
password: "",
useRefreshTokens: false
};
$scope.message = "";
$scope.login = function () {
authService.login($scope.loginData).then(function (response) {
$location.path('/orders');
},
function (err) {
$scope.message = err.error_description;
});
};
$scope.authExternalProvider = function (provider) {
var redirectUri = location.protocol + '//' + location.host + '/authcomplete.html';
var externalProviderUrl = ngAuthSettings.apiServiceBaseUri + "api/Account/ExternalLogin?provider=" + provider
+ "&response_type=token&client_id=" + ngAuthSettings.clientId
+ "&redirect_uri=" + redirectUri;
window.$windowScope = $scope;
var oauthWindow = window.open(externalProviderUrl, "Authenticate Account", "location=0,status=0,width=600,height=750");
};
$scope.authCompletedCB = function (fragment) {
$scope.$apply(function () {
if (fragment.haslocalaccount == 'False') {
authService.logOut();
authService.externalAuthData = {
provider: fragment.provider,
userName: fragment.external_user_name,
externalAccessToken: fragment.external_access_token
};
$location.path('/associate');
}
else {
//Obtain access token and redirect to orders
var externalData = { provider: fragment.provider, externalAccessToken: fragment.external_access_token };
authService.obtainAccessToken(externalData).then(function (response) {
$location.path('/orders');
},
function (err) {
$scope.message = err.error_description;
});
}
});
}
}]);
authComplete.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<script src="scripts/authComplete.js"></script>
</body>
</html>
authComplete.js
window.common = (function () {
var common = {};
common.getFragment = function getFragment() {
if (window.location.hash.indexOf("#") === 0) {
return parseQueryString(window.location.hash.substr(1));
} else {
return {};
}
};
function parseQueryString(queryString) {
var data = {},
pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;
if (queryString === null) {
return data;
}
pairs = queryString.split("&");
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i];
separatorIndex = pair.indexOf("=");
if (separatorIndex === -1) {
escapedKey = pair;
escapedValue = null;
} else {
escapedKey = pair.substr(0, separatorIndex);
escapedValue = pair.substr(separatorIndex + 1);
}
key = decodeURIComponent(escapedKey);
value = decodeURIComponent(escapedValue);
data[key] = value;
}
return data;
}
return common;
})();
var fragment = common.getFragment();
window.location.hash = fragment.state || '';
window.opener.$windowScope.authCompletedCB(fragment);
window.close();
The issue I am having is that when I run the application on a mobile device (Safari, Chrome for Mobile), the social login window opens in a new tab and the JS function which was intended to pass back the fragment to the main application window does not execute nad the new tab does not close.
You can actually try this behavior on both a desktop and mobile browser through the application:
http://ngauthenticationapi.azurewebsites.net/
What I have tried so far in this context is in the login controller, I modified the function so that the external login url opens in the same window:
$scope.authExternalProvider = function (provider) {
var redirectUri = location.protocol + '//' + location.host + '/authcomplete.html';
var externalProviderUrl = ngAuthSettings.apiServiceBaseUri + "api/Account/ExternalLogin?provider=" + provider
+ "&response_type=token&client_id=" + ngAuthSettings.clientId
+ "&redirect_uri=" + redirectUri;
window.location = externalProviderUrl;
};
And modified the authComplete.js common.getFragment function to return to the login page, by appending the access token provided by the social login as query string:
common.getFragment = function getFragment() {
if (window.location.hash.indexOf("#") === 0) {
var hash = window.location.hash.substr(1);
var redirectUrl = location.protocol + '//' + location.host + '/#/login?ext=' + hash;
window.location = redirectUrl;
} else {
return {};
}
};
And in the login controller, I added a function to parse the querystring and try to call the $scope.authCompletedCB(fragment) function like:
var vm = this;
var fragment = null;
vm.testFn = function (fragment) {
$scope.$apply(function () {
if (fragment.haslocalaccount == 'False') {
authenticationService.logOut();
authenticationService.externalAuthData = {
provider: fragment.provider,
userName: fragment.external_user_name,
externalAccessToken: fragment.external_access_token
};
$location.path('/associate');
}
else {
//Obtain access token and redirect to orders
var externalData = { provider: fragment.provider, externalAccessToken: fragment.external_access_token };
authenticationService.obtainAccessToken(externalData).then(function (response) {
$location.path('/home');
},
function (err) {
$scope.message = err.error_description;
});
}
});
}
init();
function parseQueryString(queryString) {
var data = {},
pairs, pair, separatorIndex, escapedKey, escapedValue, key, value;
if (queryString === null) {
return data;
}
pairs = queryString.split("&");
for (var i = 0; i < pairs.length; i++) {
pair = pairs[i];
separatorIndex = pair.indexOf("=");
if (separatorIndex === -1) {
escapedKey = pair;
escapedValue = null;
} else {
escapedKey = pair.substr(0, separatorIndex);
escapedValue = pair.substr(separatorIndex + 1);
}
key = decodeURIComponent(escapedKey);
value = decodeURIComponent(escapedValue);
data[key] = value;
}
return data;
}
function init() {
var idx = window.location.hash.indexOf("ext=");
if (window.location.hash.indexOf("#") === 0) {
fragment = parseQueryString(window.location.hash.substr(idx));
vm.testFn(fragment);
}
}
But obviously this is giving me an error related to angular (which I have no clue at the moment):
https://docs.angularjs.org/error/$rootScope/inprog?p0=$digest
So, pretty much it is a dead end for me at this stage.
Any ideas or input would be highly appreciated.
Gracias!
Update: I managed to resolve the Angular error about the rootscope being thrown, but sadly, resolving that does not fix the main issue. If I tried to open the social login on the same browser tab where my application is, Google can login and return to the application and pass the tokens required. It is a different story for Facebook, where in the Developer's tools console, there is a warning that seems to stop Facebook from displaying the login page.
Pretty much, the original method with which a new window (or tab) is opened is the way forward but fixing the same for mobile browser seems to be getting more challenging.
On desktop, when the auth window pops up (not tab) it has the opener property set to the window which opened this pop up window, on mobile, as you said, its not a pop up window but a new tab. when a new tab is opened in the browser, the opener property is null so actually you have an exception here:
window.opener.$windowScope.authCompletedCB
because you can't refer the $windowScope property of the null value (window.opener) so every line of code after this one wont be executed - thats why the window isn't closed on mobile.
A Solution
In your authComplete.js file, instead of trying to call
window.opener.$windowScope.authCompletedCB and pass the fragment of the user, save the fragment in the localStorage or in a cookie (after all the page at authComplete.html is in the same origin as your application) using JSON.stringify() and just close the window using window.close().
In the loginController.js, make an $interval for something like 100ms to check for a value in the localStorage or in a cookie (don't forget to clear the interval when the $scope is $destroy), if afragment exist you can parse its value using JSON.parse from the storage, remove it from the storage and call $scope.authCompletedCB with the parsed value.
UPDATE - Added code samples
authComplete.js
...
var fragment = common.getFragment();
// window.location.hash = fragment.state || '';
// window.opener.$windowScope.authCompletedCB(fragment);
localStorage.setItem("auth_fragment", JSON.stringify(fragment))
window.close();
loginController.js
app.controller('loginController', ['$scope', '$interval', '$location', 'authService', 'ngAuthSettings',
function ($scope, $interval, $location, authService, ngAuthSettings) {
...
// check for fragment every 100ms
var _interval = $interval(_checkForFragment, 100);
function _checkForFragment() {
var fragment = localStorage.getItem("auth_fragment");
if(fragment && (fragment = JSON.parse(fragment))) {
// clear the fragment from the storage
localStorage.removeItem("auth_fragment");
// continue as usual
$scope.authCompletedCB(fragment);
// stop looking for fragmet
_clearInterval();
}
}
function _clearInterval() {
$interval.cancel(_interval);
}
$scope.$on("$destroy", function() {
// clear the interval when $scope is destroyed
_clearInterval();
});
}]);
pushState doesn't make a request, it just changes the url and stores a new history entry. Thinking about this concept, it's impossible to refresh or bookmark because the server will always do a request. A server-side solution is needed.
After several hours searching, I have found a solution, every single call must be redirect to index.php to let PHP handle the request.
rewrite ^/(.*)$ /index.php?page=$1 last
I don't know exactly how this file should be to let a website refresh or bookmark a page. Can somebody help me ? I made an example to help clarify.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title>History API</title>
<script>
function ajax (url, callback) {
var conection = new XMLHttpRequest ();
conection.open ("GET", url, true);
conection.setRequestHeader ("X-Requested-With", "XMLHttpRequest");
conection.send (null);
conection.onreadystatechange = function () {
if (conection.readyState === 4) {
if (conection.status === 200) {
callback (conection.responseText);
}
else if (conection.status === 404) {
alert ("Page not found !");
}
else {
alert ("Error !");
}
}
}
}
window.addEventListener ("popstate", function (event) {
var state = event.state;
if (state) {
document.getElementById ("content").innerHTML = state["content"];
}
});
document.addEventListener ("DOMContentLoaded", function () {
var content = document.getElementById ("content");
var menu = document.getElementById ("menu");
menu.addEventListener ("click", function (event) {
var target = event.target;
if (target.nodeName === "A") {
ajax (target.href, function (result) {
history.pushState ({"content": result}, target.innerHTML, target.href);
content.innerHTML = result;
});
event.preventDefault ();
}
});
});
</script>
<style>
body {
width: 400px;
}
div {
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<body>
<div id = "menu">
Page 1
Page 2
</div>
<div id = "content"></div>
</body>
</html>
index.php
<?php
isset ($_GET["page"]) or exit ("Error !");
$page = $_GET["page"];
// Ajax request
if (isset ($_SERVER["HTTP_X_REQUESTED_WITH"]) && strtolower ($_SERVER["HTTP_X_REQUESTED_WITH"]) === "xmlhttprequest") {
if (file_exists ($page)) {
require_once ($page);
}
else {
header ("HTTP/1.1 404 Not Found");
}
}
else {
require_once ("index.html");
}
?>
page1.html
Hello, I'm the Page 1. It's nice to meet you.
page2.html
Hi brother. I'm page 2.
Clicking (ok)
Refresh (fails)
First of all you should really not use a GET parameter as input for a _require_once_. Really. Not. Use at least a simple whitelist of allowed names for pages and only include and output mapped files (or files with those whitelisted names).
Now to your history API problem. Pushing things obviously seems to work for you so all that is missing is probably a simple ondomready event that reads the current URL and loads the content via AJAX or from existing history entries. The same whitelist approach should be used there. Also try to not fall into the trap of DOMXSS by using unvalidated input (the URL) as input for your javascript and DOM operations.