I want to generate JWT using JavaScript on HTML page.
I looked at Online JWT service Click Here, but can't get proper idea.
So is there any solution to generate JWT using JavaScript in HTML page.
I've encode and decode method in c# code. but i want to encode parameter from java script and will decode in c# code.
My c# Code look like:
public static string Encode(object payload, byte[] key, JwtHashAlgorithm algorithm)
{
var segments = new List<string>();
var header = new { typ = "JWT", alg = algorithm.ToString() };
byte[] headerBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(header));
byte[] payloadBytes = Encoding.UTF8.GetBytes(jsonSerializer.Serialize(payload));
segments.Add(Base64UrlEncode(headerBytes));
segments.Add(Base64UrlEncode(payloadBytes));
var stringToSign = string.Join(".", segments.ToArray());
var bytesToSign = Encoding.UTF8.GetBytes(stringToSign);
byte[] signature = HashAlgorithms[algorithm](key, bytesToSign);
segments.Add(Base64UrlEncode(signature));
return string.Join(".", segments.ToArray());
}
public static string Decode(string token, byte[] key, bool verify = true)
{
var parts = token.Split('.');
var header = parts[0];
var payload = parts[1];
byte[] crypto = Base64UrlDecode(parts[2]);
var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header));
var headerData = jsonSerializer.Deserialize<Dictionary<string, object>>(headerJson);
var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload));
if (verify)
{
var bytesToSign = Encoding.UTF8.GetBytes(string.Concat(header, ".", payload));
var keyBytes = key;
var algorithm = (string)headerData["alg"];
var signature = HashAlgorithms[GetHashAlgorithm(algorithm)](keyBytes, bytesToSign);
var decodedCrypto = Convert.ToBase64String(crypto);
var decodedSignature = Convert.ToBase64String(signature);
if (decodedCrypto != decodedSignature)
{
throw new SignatureVerificationException(string.Format("Invalid signature. Expected {0} got {1}", decodedCrypto, decodedSignature));
}
}
return payloadJson;
}
Your answer will appreciable.
Thanks,
Hardik
Related
I am working on a spring boot web application, where I want to upload multiple images of a product at a time along with other fields (for example product name, SKU code, category, tags, subcategory, etc). I have written code for RESTful API to upload multiple images and it is working perfectly for me. I tested API using postman and it is working fine. But, I don't know how to do it from the front end. I am showing you my front-end code below, where I am sending a single image to my controller using Ajax.
$("#file").change(function(){
var formData = new FormData();
var fileSelect = document.getElementById("file");
if(fileSelect.files && fileSelect.files.length == 1) {
var file = fileSelect.files[0];
formData.set("file",file,file.name);
}else{
$("#file").focus();
return false;
}
var request = new XMLHttpRequest();
try {
request.onreadystatechange=function() {
if(request.readyState==4) {
var v = JSON.parse(request.responseText);
if(v.status==="OK") {
alert("Product Image Uploaded Successfully")
document.getElementById('imagepath').value = v.response;
}
}
}
request.open('POST',"<%=AkApiUrl.testuploadfile%>");
request.send(formData);
} catch(e) {
swal("Unable to connect to server","","error");
}
});
As I told you, the above code is to send a single file at a time. I am showing you my API controller code also:
#RequestMapping(value = AkApiUrl.testuploadfile, method = { RequestMethod.POST, RequestMethod.GET }, produces = {MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity<?> testuploadfile(HttpServletRequest request, #RequestParam("files") MultipartFile[] files) {
CustomResponse = ResponseFactory.getResponse(request);
String imgurl = "NA";
try {
String path = Constants.webmedia;
String relativepath = "public/media/";
System.out.println("Here is the image: ");
List<MultipartFile> multifile = Arrays.asList(files);
if( null != multifile && multifile.size()>0) {
for (int i=0; i < multifile.size(); i++) {
String filename = files[i].getOriginalFilename();
String extension = filename.substring(filename.lastIndexOf("."), filename.length());
int r = (int )(Math.random() * 500 + 1);
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss");
Date date = new Date();
String formatdate = format.format(date);
formatdate = "ECOM" + formatdate + r;
byte[] bytes = files[i].getBytes();
BufferedOutputStream stream = new BufferedOutputStream( new FileOutputStream(new File(path + File.separator + formatdate + extension)));
stream.write(bytes);
stream.flush();
stream.close();
String newimgurl = relativepath + formatdate + extension;
imgurl = imgurl+"##"+newimgurl;
if(imgurl != null) {
CustomResponse.setResponse(imgurl);
CustomResponse.setStatus(CustomStatus.OK);
CustomResponse.setStatusCode(CustomStatus.OK_CODE);
}
}
}
} catch (Exception e) {
e.printStackTrace();
CustomResponse.setResponse(null);
CustomResponse.setStatus(CustomStatus.Error);
CustomResponse.setStatusCode(CustomStatus.Error_CODE);
CustomResponse.setResponseMessage(CustomStatus.ErrorMsg);
}
return new ResponseEntity<ResponseDao>(CustomResponse, HttpStatus.OK);
}
This API is working fine, I am getting desired response. But I do not know how should I implement this thing on the JSP page. Please, any suggestions would be appreciated.
At my front-end, I am currently creating a FormData object that contains an array with the following properties: "ProductId" and "UserImage". Just to give more context, the "UserImage" property will receive a blob (image). The blob is generated with the following 2 methods: "imagetoblob" and "b64toBlob". Whenever I tried to send the FormData to my server-side, my controller will freeze for about 45 seconds and return a Network Error message. Hence, I am unable to bind the values from the FormData to my model class (Product). However, when I remove the UserImage variable from my model class, I was able to successfully send and bind the formData.
// public IFormFile UserImage { get; set; } // remove
What seems to be the problem? Below is my code and screenshots of my error
Update I am still trying to solve this issue. Any help is greatly appreciated!
Client-Side
// Assuming I have the base64URL values
var base64Image1 = "";
var base64Image2 = "";
const formData = new FormData();
formData.append("Products[0].ProductId", "1");
formData.append("Products[0].UserImage", imagetoblob(base64Image1));
formData.append("Products[1].ProductId", "1");
formData.append("Products[1].UserImage", imagetoblob(base64Image2));
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || "";
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (
var offset = 0;
offset < byteCharacters.length;
offset += sliceSize
) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, { type: contentType });
return blob;
}
function imagetoblob(base64Image) {
// Split the base64 string in data and contentType
var block = base64Image.split(";");
// Get the content type of the image
var contentType = block[0].split(":")[1]; // In this case "image/gif"
// get the real base64 content of the file
var realData = block[1].split(",")[1]; // In this case "R0lGODlhPQBEAPeoAJosM...."
// Convert it to a blob to upload
return b64toBlob(realData, contentType);
}
Server-side (Controller)
[HttpPost("verifyCart")]
public async Task<IActionResult> verifyCart([FromForm] List<Product> products)
{
}
Server-Side (Model class)
public class Product
{
public int ProductId { get; set; }
public IFormFile UserImage { get; set; }
}
FormData's UserImage key contains the blob (file) -- client side
Network Error received from client-side
Able to receive and bind FormData after removing the IFormFile UserImage at the model class --Server-side
I think your main issues are how you appending your files to your formData and the type you are using in your model.
This is what I would do if I was you:
formData.append("UserImage", imagetoblob(base64Image1));
formData.append("UserImage", imagetoblob(base64Image2));
You can append multiple files here to the same 'UserImage' key.
public class Product
{
public int ProductId { get; set; }
public List<IFormFile> UserImage { get; set; }
}
In your model use a List as your data type.
This should work for single file or multiple file uploads.
I am trying to convert an image to base64 to upload it on sharepoint site but it is throwing 400:bad request error. when i checked properly then i found out that the base64 i am sending is endcoded by javascript and it is different than what is expected by sharepoint. I have attached 2 images here describing the difference. Can anyone help me to get the proper encoded data using javascript ?
javascript encoded base64
c# encoded base64
var files = $("#myfile").get(0).files;
var reader = new FileReader();
reader.readAsDataURL(files[0]);
reader.onload = function () {
console.log(reader.result);
}
Could try : reader.result.split("base64,")[1]
Removes the "base64," start of the string.
Please try this , i am using this in my project , its working for me
if (file.ContentType.Contains("image"))
{
string theFileName = Path.GetFileName(file.FileName);
byte[] thePictureAsBytes = new byte[file.ContentLength];
using (BinaryReader theReader = new BinaryReader(file.InputStream))
{
thePictureAsBytes = theReader.ReadBytes(file.ContentLength);
}
string thePictureDataAsString = Convert.ToBase64String(thePictureAsBytes);
}
"thePictureDataAsString " variable got Base64 string
.........................................................................
i am getting file like this in my project
public ActionResult SaveMake(string inputMakeName, HttpPostedFileBase file)
{
MakeModel objMakeModel = new MakeModel();
if (file.ContentType.Contains("image"))
{
string theFileName = Path.GetFileName(file.FileName);
byte[] thePictureAsBytes = new byte[file.ContentLength];
using (BinaryReader theReader = new BinaryReader(file.InputStream))
{
thePictureAsBytes = theReader.ReadBytes(file.ContentLength);
}
string thePictureDataAsString = Convert.ToBase64String(thePictureAsBytes);
objMakeModel.ImageBase64 = thePictureDataAsString;
objMakeModel.Make1 = inputMakeName;
}
string response = _apiHelper.ConvertIntoReturnStringPostRequest<MakeModel>(objMakeModel, "api/Transaction/SaveMakes/");
// string response = _apiHelper.SaveMake(objMakeModel, "api/Transaction/SaveMakes/");
return RedirectToAction("AddVehicleMaintenance");
}
I'm try to decode protobuf message from server side (base64 string) to javascript object. Use for decode protobuf.js.
As doc suggest :
var builder = ProtoBuf.newBuilder({ convertFieldsToCamelCase: true });
var YourMessage = builder.build("YourMessage");
var buffer = ...; // E.g. a buffer received on a WebSocket
var myMessage = YourMessage.decode(buffer);
...
var b64str = ...; // E.g. a string fetched via AJAX
var myMessage = YourMessage.decode64(b64str);
This is how I try to do it (data - base64 string) :
var proto = dcodeIO.ProtoBuf;
var buffer = dcodeIO.ByteBuffer;
var b = buffer.wrap(data,"binary");
var builder = proto.newBuilder({ convertFieldsToCamelCase: true });
builder.define("Events");
var message = builder.build("Events");
var result = message.decode(b); //also try to decode base64 string - message.decode64(data);
I get error
decode/decode64 undefined
Missing the line to import the proto definition as below (where tests/example1.proto is your file name)
ProtoBuf.loadProtoFile("tests/example1.proto", builder);
or if loading from proto string
ProtoBuf.loadProto(...protoString..., "example1.proto");
without this the builder will say undefined because there is nothing for it to build its definition with
What ways are there for a website to detect automated connections made through C# Httpwebrequest?
Such as c#'s default user-agent? Operating System? or what..
have this problem with any other language, just C#?
I'm being blocked from accessing a certain website using Httpwebrequest, I don't
Also it's definitely not my IP address & nor are there any faults in my code as I've tested connections to other websites which work just fine.. Also I stated above I can make connections to the website using C++, C, Vb.net, Java, Python & so on, there is also no difference in header information either.
EDIT:
// Create a request using a URL that can receive a post.
WebRequest request = WebRequest.Create ("http://services.runescape.com/m=hiscore_oldschool/overall.ws");
// Set the Method property of the request to POST.
request.Method = "POST";
// Create POST data and convert it to a byte array.
string postData = "user1=Zezima&submit=Search";
byte[] byteArray = Encoding.UTF8.GetBytes (postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Set the ContentLength property of the WebRequest.
request.ContentLength = byteArray.Length;
// Get the request stream.
Stream dataStream = request.GetRequestStream ();
// Write the data to the request stream.
dataStream.Write (byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close ();
// Get the response.
WebResponse response = request.GetResponse ();
// Display the status.
Console.WriteLine (((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream ();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader (dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd ();
// Display the content.
Console.WriteLine (responseFromServer);
// Clean up the streams.
reader.Close ();
dataStream.Close ();
response.Close ();
private const string Url = "http://services.runescape.com/m=hiscore_oldschool/overall.ws";
private static HttpWebRequest BuildWebRequest()
{
var request = WebRequest.Create(Url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = 40000;
request.ServicePoint.Expect100Continue = true;
string body = "user1=Zezima&submit=Search";
byte[] bytes = Encoding.Default.GetBytes(body);
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
return request;
}
static void Main(string[] args)
{
try
{
HttpWebRequest request = BuildWebRequest();
var response = request.GetResponse() as HttpWebResponse;
var responseContent = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.Write("Success - " + response.StatusCode);
}
catch (Exception e)
{
Console.Write(e);
}
}
I can take the response from the website. It is not empty.