Google Sign In : Decoding JWT response - google-signin

I have applied Google Sign In code; Everything is properly working. Now want to decode the jwt response. Can you please suggest how this decodeJwtResponse is formed.
Please Help.
function handleCredentialResponse(response) {
const responsePayload = decodeJwtResponse(response.credential);
console.log("ID: " + responsePayload.sub);
console.log('Full Name: ' + responsePayload.name);
console.log('Given Name: ' + responsePayload.given_name);
console.log('Family Name: ' + responsePayload.family_name);
console.log("Image URL: " + responsePayload.picture);
console.log("Email: " + responsePayload.email);
}

you can use jtw.io to decode the token and looks to everything included in the response (claims/audience/etc...)

Download the appropriate parsing mechanism form jwt.io. it has decoders for nodejs, .net, and more and you did not specify what you are using. Also note that you want to send the non-decoded version to the Google API for validation, the next and important step in the document I believe you obtained that code from.

You can use the jsonwebtoken library
After installing with npm i jsonwebtoken
import jwt from "jsonwebtoken";
function decodeJwtResponse(credential){
return jwt.decode(credentail)
}
function handleCredentialResponse(response) {
const responsePayload = decodeJwtResponse(response.credential);
console.log("ID: " + responsePayload.sub);
console.log('Full Name: ' + responsePayload.name);
console.log('Given Name: ' + responsePayload.given_name);
console.log('Family Name: ' + responsePayload.family_name);
console.log("Image URL: " + responsePayload.picture);
console.log("Email: " + responsePayload.email);
}

Related

Sign In with Google - Console.log

I'm trying to use this new example for the new Sign In with Google since oAuth will be retired in 2023. Question is, how do I pass this value console.log("Email: " + responsePayload.email); to a hidden html field ? I was able to do this with the current oAuth Java funstion but can't seem to pass the value with this new version of the code.
decodeJwtResponse() is a custom function defined by you - could be what I'm missing. I would like to keep this entire function in java script if possible. I am lost
<div id="g_id_onload"
data-client_id="YOUR_GOOGLE_CLIENT_ID"
data-callback="handleCredentialResponse">
</div>
<script>
function handleCredentialResponse(response) {
// decodeJwtResponse() is a custom function defined by you
// to decode the credential response.
const responsePayload = decodeJwtResponse(response.credential);
console.log("ID: " + responsePayload.sub);
console.log('Full Name: ' + responsePayload.name);
console.log('Given Name: ' + responsePayload.given_name);
console.log('Family Name: ' + responsePayload.family_name);
console.log("Image URL: " + responsePayload.picture);
console.log("Email: " + responsePayload.email);
}
</script>
To decode the token you need to Base64 URL decode the message and parse it back into an object with JSON.parse, which is what jwt-decode does.
If you're not using a bundler with NPM you can import it:
console.log(jwt_decode('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'))
<script src="https://unpkg.com/jwt-decode/build/jwt-decode.js"></script>
Or as an ES6 module:
<script type="module">
// Or https://unpkg.com/jwt-decode/build/jwt-decode.esm.js
import jwtDecode from 'https://esm.run/jwt-decode';
console.log(jwtDecode('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'))
</script>
I was able to do it manually using https://jwt.io/ with algorithm RS256
And programmatically using jose library https://github.com/panva/jose
import * as jose from 'jose'
const claims = jose.decodeJwt(token)
console.log(claims)
The result is the same as in the documentation https://developers.google.com/identity/gsi/web/reference/js-reference#credential
You should verify the JWT (public keys, issuer, audience, issuer and expiration date), jose has a function to decode and verify called jwtVerify
https://github.com/panva/jose/blob/main/docs/functions/jwt_verify.jwtVerify.md#readme

ERR_CONNECTION_RESET when downloading PDF with POST from ASP.Net Core controller

I created an endpoint that takes a json body from a POST request, uses that data to fill in the fields of a PDF, and send the filled out file back. When I try to send a POST request using Send and Download on Postman, I initially get a 200 OK back and Postman goes into a loading state, showing how much time the download has taken so far.
After about 2 minutes of this, I get an ECONNRESET error:
Thinking this was just a problem with Postman, I updated a React project of mine to hit the endpoint. I was expecting making the request would start the browser's built in file download feature. Instead, I got a similar error: ERR_CONNECTION_RESET.
I debugged my controller and it seems to be parsing the request body correctly. It also doesn't seem to take too long to return from the endpoint's function. I'm using the File method from ControllerBase to make the response from the file stream, and I make sure not to dispose of the file stream too early.
Per Ali Vahidinasab's request, here is the Postman request exported to C#:
var client = new RestClient("https://localhost:44398/api/charactersheet/download");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/pdf");
var body = #"{
" + "\n" +
#" ""abilityScores"": {
" + "\n" +
#" ""strength"": 10,
" + "\n" +
#" ""dexterity"": 11,
" + "\n" +
#" ""constitution"": 12,
" + "\n" +
#" ""intelligence"": 13,
" + "\n" +
#" ""wisdom"": 14,
" + "\n" +
#" ""charisma"": 15
" + "\n" +
#" }
" + "\n" +
#"}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine($"Status Code: {response.StatusCode}");
When I ran this client code, the response had a status code of 0, which I understand means that there is no response from the server.
I guess the crux of this question is: is this an issue with the server or the client? And what can I do to fix it?
I found the issue. It was on the server side. I had to set the position of the memory stream I was returning to 0 before returning it.

Karate - Authentication - cannot access url address under password

Using Karate, I have need to use basic authentication (to pass common authentication dialog window with username and password), and I have tried this: https://github.com/intuit/karate#http-basic-authentication-example).
I have created the file basic-auth.js
function fn(creds) {
var temp = creds.username + ':' + creds.password;
var Base64 = Java.type('java.util.Base64');
var encoded = Base64.getEncoder().encodeToString(temp.bytes);
return 'Basic ' + encoded;
}
I have added the call to the test feature file I run (added to Scenario section):
header Authorization = call read('basic-auth.js') { username: 'realusernamestring', password: 'realpasswordstring' }
Then I have placed the url I want to access right after:
driver urlUnderPassword
But it did not work, I still cannot access the page. I think there is something missing, something what needs to be done. Could you help me what the problem might be?
Thank you.
What you are referring to is for API tests not UI tests.
If you need the browser / driver to do basic auth it should be easy, just put it in the URL: https://intellipaat.com/community/10343/http-basic-authentication-url-with-in-password
So I am guessing something like this will work:
* driver 'http://' + username + ':' + password + '#' + urlUnderPassword

Firebase and busboy, do I get the whole file in memory, or?

I want to upload rather large files in a node.js/Firebase project. I am trying to understand if Busboy fits my need.
The example in the Busboy documentation ends with
req.pipe(busboy);
However this does not work in Firebase. It looks like you instead should use
busboy.end(req.rawBody);
That works for me (at least locally, under firebase serve. However there is a difference, perhaps. In the example I mentioned above you have this:
if (req.method === 'POST') {
let busboy = new Busboy({ headers: req.headers });
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
file.on('data', (data) => {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
});
I expected to see several outputs from file.on("data", ...), but there is just one line for a 100 MB file. Does this mean that the whole file is kept in memory?
EDIT: The busboy.end(req.rawBody) is from https://cloud.google.com/functions/docs/writing/http#multipart_data
The entire request and response for Cloud Functions input and output is kept entirely in memory before being transferred to and from the client. The maximum payload size for requests and responses is 10MB, as shown in the documentation.
When working with large files, you should consider uploading to Cloud Functions, then trigger a function from there.

'#' in URL, used in node.js http.request

I'm presented with an url with an "#" sign in it:
curl http://subdomain:token#localhost:9292/aaa/bbb
works perfectly
But I can't get it to work with node.js http.request, probably because I don't understand what the "#" is doing (and somehow can't find a clear answer on google).
Anyone care to explain?
Here's my current node.js code
var http_options = {
method : "GET"
, url : subdomain + ":" + token + "#" + Config.API.url
, path : "/aaa/bbb"
};
var req = http.request(http_options, function (response) {
// ...
});
req.on('error', function (error) {
console.log('error: ' + error);
});
which produces:
error: ECONNREFUSED
The # is dividing the user / password part from the location part.
the curl line you wrote send a HTTP Authenticate (BASIC authentication) with the request.
curl http://subdomain:token#localhost:9292/aaa/bbb
means: Get localhost:9292/aaa/bbb and do it as user: subdomain password token
I have no idea how to do that in node.js, but you'll figure it out, now that you know what it does.

Resources