Google is mandating an upgrade to their authentication/authorization mechanism, deprecating their existing mechanism.
The entire "GoogleAuth" object and all methods is deprecated.
The migration guidelines provide old->new guidance and examples (many of which don't work as described, but that's another story).
The old GoogleAuth object had one particularly necessary method .getUserInfo().
The docs do not provide a migration path for most methods on this object, and not for this one. (The migration doc merely says "remove" with regard to this method.) None of the sample code in migration offer guidance for this.
There is a companion set of docs that describe a different code path, that seems not-entirely-compatible with the new Google Identity Service, and which suggests the user data is embedded in a JWT, but offers no guidance on how to decrypt that JWT.
My code for authenticating, authorizing, and accessing google's api's is more or less functional (still pops a dialog on every new page load, still working on that), but getting the user info has defeated me after scrutinizing every migration doc, code sample, and considerable searching.
Has anyone cracked this nut?
I am terribly afraid that the answer is so simple that I have spent a full day banging my head on my own stupidity.
I'm even more afraid it's not possible!
Yes, it is possible. I understand your frustration but your "question" is more about expressing your frustration instead of explaining what you've done so far so we can help you. However, let me try to provide as much help as possible.
As you already find out, the "Google Identity Services" is separating "Authorization" and "Authentication" into two different things. (In my personal opinion, this makes it harder for us developers, although they[google] claim is more secure but I don't see that).
I presume that you need the "Authentication" part since you need the user information. In that case, you have to follow the guide documented here.
If you will be using the "Sign In With Google" button or the "One Tap" prompt, is up to you. I decided to go with the "One Tap" prompt. Once you get back the credentials response, you have to decode the JWT that comes in the response. There are many JWT libraries you can use, for the purpose of this example, I am using this one: https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js, however is your responsibility to find a secure library that allows you to do that, hence Google is not recommending any.
Here is an example of the code I'm using:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://accounts.google.com/gsi/client" async defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js"></script>
</head>
<body>
<h1>Hello World!</h1>
<div id="signinBox"></div>
<script src="app.js"></script>
</body>
</html>
app.js
window.onload = function () {
google.accounts.id.initialize({
client_id: 'blablabla.apps.googleusercontent.com',
callback: handleCredentialResponse,
ux_mode: "redirect",
prompt_parent_id: "signinBox",
context: "signin",
cancel_on_tap_outside: false,
auto_select: true
});
google.accounts.id.prompt((notification) => {
if(notification.isNotDisplayed() || notification.isSkippedMoment()) {
console.log("Prompt cancelled by user");
}
});
};
const handleCredentialResponse = (credsResponse)=>{
console.log(credsResponse);
var headerObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(credsResponse.credential.split(".")[0]));
var payloadObj = KJUR.jws.JWS.readSafeJSONString(b64utoutf8(credsResponse.credential.split(".")[1]));
console.log(headerObj);
console.log(payloadObj);
};
After running the above example, you will see the user information in the "payloadObj". It should have all the information as explained here.
Related
Something I've recently done on a few sites I've developed for is to create an included JavaScript function which prints an email address based off of an argument. An example below:
/index.html
...
<head>
<script src="/script/main.js></script>
</head>
<body>
...
<p><script>printEmail('info');</script></p>
...
/script/main.js
function printEmail(a) {
document.write('' + a + '#domain.com');
}
The thought process that I have is that the relatively small script should help deter spambots by not including the email address in full anywhere in the source code. The only place it becomes readable is through the rendering engine.
So is it secure? Also, how secure is it compared to other prevention methods?
If it renders to the page on page load, I don't think this would do anything, since the spam bots would wait for the page to load anyways and then grab the emails.
If you make a user action required, like hovering over the email to reveal the full email, at which point the javascript prints it out, I think that would be more effective, and I've seen things like that in use on pages before.
I'd like to write a simple javascript embeddable widget that displays some information retrieved from the API of my application.
The API I'm building is written in Symfony2 and I'm trying to simply get the resulting JSON string and display it in a demo HTML page using javascript.
To get the JSON string I'm trying to use some code I found here on Stackoverflow.
The complete Javascript code I'm using is the following:
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
document.body.className = 'ok';
} else {
document.body.className = 'error';
}
}
};
var url = 'http://127.0.0.1:8000/widget/1';
request.open("GET", url, true);
request.send(null);
document.getElementById('demo').innerHTML = request;
The HTML is a simple page like this:
<!DOCTYPE html>
<html lang="it">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8" />
<meta name="generator" content="Aerendir's Hands" />
<title>Widget demo page</title>
</head>
<body>
<h1>Pagina demo del widget di TrustBack.Me</h1>
<p id="demo"></p>
<script src="widget.js"></script>
</body>
</html>
When I open http://localhost/demo.html, the Chrome console tells me:
XMLHttpRequest cannot load http://127.0.0.1:8000/widget/1. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
I understand that this is a security measure to prevent some kind of Cross Site Scripting, but how Facebook can do those kind of requests with its widgets?
Fortunately I'm using http://127.0.0.1 and http://localhost, so this problem turned out immediately! (I think this is the cause of the error o.O).
How can I get the JSON string from my application to use it in my javascript code?
I'm really good at PHP and Symfony2, but I have no knowledge of JavaScript and this is my first attempt to learn it.
So I hope someone here can help me to better understand the mechanics behind a widget.
I've read a lot of posts about how to build a javascript widget here on Stackoverflow and on the Internet, but I cannot find something current: all resources I've found are old (max 2012) and I'm not sure they can be useful or still relevant.
Usually I read some documentation to have an idea of what to do and then I start trying, but in this case, as I have no previous knowledge about best practices and as I don't know the Javascript language, I cannot recognize good advices and cannot separate the current good advices from the old and useless ones.
I know Facebook uses iFrames and my knowledge and comprehension stops here.
Can someone put me on the right direction to achieve my goal?
My goal, in this moment, is to have a javascript variable with the json string returned by my remote API.
Thankyou in advance!
Am writing my first websocket program and am getting "WebSocket handshake: Unexpected response code: 404", error while loading the webpage.
I am using JDK 1.7 and jboss 8 (wildfly8.0).
Could anyone please assist?
window.onload = init;
var socket = new WebSocket("ws://localhost:8080/WebsocketHome/actions");
socket.onmessage = onMessage;
and head in html
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="websocket.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
Thank you guys for your suggestion, I found the answer.
The code I copied is from http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html site.
The problem was the url as mentioned in the js file and the project name they are proposing is WebsocketHome. I had changed the project name to Websocket thus my url should be ws://localhost:8080/Websocket/actions.
Thanks for your support.
Actually, the problem here is case-sensitivity in the URLs. You did not need to change the project name. Just changing the Websocket URL in JavaScript file to
ws://localhost:8080/WebSocketHome/actions
(with capital S, as in the project name) would have solved the problem. In your case, changing both of them removed the case inconsistency, so it worked.
It's because of the issue of /info=34424 - with 404 error - that I had to abandon using the xml approach suggested at other places. I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldung worked(for me without changing from Spring 4.2 to 5). After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.3.RELEASE</version>
</dependency>
Baeldung's implementation curiously does not make any such calls
flow/websocket/add/info?t=1540813753999
What it does (on send and receive) is below. I am only pasting it in case people well-versed with these libraries can further add insights on this forum.
>>> SEND
destination:/app/chat
content-length:38
{"from":"nicholas","text":"try again"}
<<< MESSAGE
destination:/topic/messages
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:m3p096zk-11
content-length:53
{"from":"nicholas","text":"try again","time":"13:46"}
My guess is that you are trying to contact the websocket with a normal browser.
That is not allowed and gives a 404 error. You need to use a script or curl to address websockets.
does anyone have an experience in embedding Visualize.js into APEX Application to integrate JasperServer Reports ?! Using the REST or iFrame is not a case i'm afraid. Not a big fan of JavaScript, but it looks like the only way this time. Done some research and didn't find any usefull info, as most of people using either REST or iFrame. Any help highly appreciated! At least show me at which direction to dig or the rough plan ... e.g do I need to upload some libraries and actually what to start with ?!
Thanks!
P.S. Apex 4.2.6 up and running, JasperServer 6.0 up and running.
I've been on Jaspersoft's visualize course and use Apex occasionally. You need to have a plain html region where you can write stuff and then use the visualize library to get reports and reports metadata from the server. You have to ensure that you are authenticated on the server and have a div or something in the dom where you can put the resulting report. You also have to grab the visualize library.
It would just be like adding any other custom html/javascript to an Apex application.
Here is a code sample to get visualize, authenticate and get a report into the dom:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<!--
<script src="http://code.jquery.com/jquery-2.1.0.js"></script>
-->
<script src="http://localhost:8080/jasperserver-pro/client/visualize.js"></script>
<script type="text/javascript">
visualize({
auth: {
name: "jasperadmin",
password: "jasperadmin"
}
}, function (v) {
var report = v.report({
resource: "/public/Samples/Reports/9.CustomerDetailReport",
container: "#container"
});
});
</script>
<body>
<div id="container"></div>
</body>
</html>
I'm just building an experimental personal site where I could log myself into gmail with the press of a button.
Everithing goes fine, when I manually go to the gmail site and type the javascript command into the url line like this and press enter:
javascript: document.getElementsByName('Email').item(0).value='name'; document.getElementsByName('Passwd').item(0).value='password'; document.getElementsByName('signIn').item(0).click(); void(0);
But when I try to do the same from a page, nothing happens... Can someone please help me out?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Test</title>
<script>
var name = 'name';
function login(url1) {
win = window.open(url1, nome);
win.document.getElementsByName('Email').item(0).value='name';
win.document.getElementsByName('Passwd').item(0).value='password';
win.document.getElementsByName('signIn').item(0).click(); void(0);
}
</script>
</head>
<body>
<button id="buton1" onclick="login('https://accounts.google.com')">GMAIL LOGIN</button>
</body>
</html>
I've checked a lot of forums and answers, and it seemed that this method should work, but it doesn't.
Now imagine that your code was followed by similar code that would send lots of spam to people using your GMail account.
Cross domain DOM manipulation is forbidden by browsers as it would be a huge security hole.
The exception is postMessage, but that requires the cooperation of both sites.
You need a browser extension for this sort of thing.