Create a pem private and public key

This is how to create a private and public pem key. And also an example no how to take use of the key in .NET.

  1. Open up git bash, cd into a folder of your preference.
  2. Enter command to create a private key:
    winpty openssl genrsa -out private.pem 2048
    Note that if you want to create a private key with a keyphrase enter in the parameter des3
  3. Create a public key based from the private key:
    winpty openssl rsa -in private.pem -outform PEM -pubout -out public.pem
  4. Now if we check in our folder we have two files:
    private.pem and public.pem

And if you would want to Create a Token or Validate a token you have methods like these in .NET (C#):

        public string CreateToken(List<Claim> claimList)
        {
            string privateKeyBytes = File.ReadAllText("./Secrets/private.pem");

            using RSA rsa = RSA.Create();
            rsa.ImportFromPem(privateKeyBytes);
            var signingCredentials = new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256)
            {
                CryptoProviderFactory = new CryptoProviderFactory { CacheSignatureProviders = false }
            };

            var now = DateTime.Now;
            var unixTimeSeconds = new DateTimeOffset(now).ToUnixTimeSeconds();

            var jwt = new JwtSecurityToken(
                issuer: "rps-auth",
                claims: claimList,
                notBefore: now,
                expires: now.AddMinutes(30),
                signingCredentials: signingCredentials
            );

            return new JwtSecurityTokenHandler().WriteToken(jwt);
        }

        public bool ValidateToken(string token)
        {
            var publicKey = File.ReadAllText("./Secrets/private.pem");

            using RSA rsa = RSA.Create();
            rsa.ImportFromPem(publicKey);

            var validationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = false,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = "rps-auth",
                IssuerSigningKey = new RsaSecurityKey(rsa),
                CryptoProviderFactory = new CryptoProviderFactory()
                {
                    CacheSignatureProviders = false
                }
            };

            try
            {
                var handler = new JwtSecurityTokenHandler();
                var principal = handler.ValidateToken(token, validationParameters, out var validatedSecurityToken);
                principal.Claims.ToList().ForEach(claim => Debug.WriteLine(claim.Value));
            }
            catch (Exception ex)
            {
                Console.WriteLine("an error... log it some way " + ex.Message);
                return false;
            }

            return true;
        }

In the above example we use the key to set a JwtSecurityToken. This would assume you have your file in a folder called Secrets where you have your public and private key. With .NET we have the System.Security.Cryptography library where we can utulize these RSA algorithm methods which makes it easy, such method is ImportFromPem which does actually what it sounds like, it will read our private key from the pem file and put it into the rsa object, which we then can get retrive a SigningCredentinals object which we then can put into a jwt property for example. The audiance property can be set with an list of Claims coming from an authentication response with claims such as firstname lastname and so forth.

For the validation part, we get to use our public key to match the incoming token with the method ValidateToken from our JwtSecurityTokenHandler object. All we need to validate it is to set some TokenValidationParameters and the most important being the actual public rsa key from our pem file.

How to use Golang and React for WebSocket

I found myself wanting to try out little bit of experimenting to learn more about web sockets, let us try it out using golang and react.

First, set up a project Golang project by creating a folder and in it, create main.go file.

Golang WebSocket Server

It’s very simple if you take use of the already great crates that are out there. One that I found working out very well with web socket is gorilla websocket.

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
}

func main() {
	http.HandleFunc("/ws", wsEndpoint)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

func wsEndpoint(w http.ResponseWriter, r *http.Request) {
	upgrader.CheckOrigin = func(r *http.Request) bool { return true }
	// upgrade this connection to a WebSocket
	// connection
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
	}

	log.Println("Client Connected")
	err = ws.WriteMessage(1, []byte("Hello client you've connected!"))
	if err != nil {
		log.Println(err)
	}
	reader(ws)
}

func reader(conn *websocket.Conn) {
	for {
		// read in a message
		messageType, p, err := conn.ReadMessage()
		if err != nil {
			log.Println(err)
			return
		}

		// print out incoming message
		fmt.Println("incoming message: " + string(p))

		if err := conn.WriteMessage(messageType, p); err != nil {
			log.Println(err)
			return
		}
	}
}

You should be able to run your program from the get-go. This is how the mod file looks:

module example.com/m/v2

go 1.15

require github.com/gorilla/websocket v1.5.0 // indirect

http.HandleFunc("/ws", wsEndpoint)

So let’s go through the code, first of all we got a main function, the starting point of the program and in it will first of all take use of the http package and set up our listeners for the endpoint /ws, which we pass in the method wsEndpoint. So each

log.Fatal(http.ListenAndServe(":8080", nil))

The ListenAndServe function will be running our actual http server and we will print out error if we get one into the log.

func wsEndpoint(w http.ResponseWriter, r *http.Request) {
	upgrader.CheckOrigin = func(r *http.Request) bool { return true }
	// upgrade this connection to a WebSocket
	// connection
	ws, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println(err)
	}

	log.Println("Client Connected")
	err = ws.WriteMessage(1, []byte("Hi Client!"))
	if err != nil {
		log.Println(err)
	}
	reader(ws)
}

Our Endpoint function takes in a ResponseWriter and a Request object which is what we need to make to make the incoming request into a websocket protocol connection with our server. This is called that we do an upgrade. From the upgrade function we get back a ws connection which we can read messages from.

func reader(conn *websocket.Conn) {
	for {
		// read in a message
		messageType, p, err := conn.ReadMessage()
		if err != nil {
			log.Println(err)
			return
		}

		// print out incoming message
		fmt.Println("incoming message: " + string(p))

		if err := conn.WriteMessage(messageType, p); err != nil {
			log.Println(err)
			return
		}
	}
}

From our reader function we can read the message from the websocket which we convert from bytes into string with help from string(p), which we then can send a response back with WriteMessage on the same socket to the client.

React WebSocket Client

Now let’s create a React project, I like to use vite to get started fast like this:

npm create vite@latest

Then go with React and nativescript. Then what web socket package I use is websocket from here: https://www.npmjs.com/package/websocket. Also remember to download the types for typescript: node_modules/@types/websocket. So we will run npm install on these:

npm i websocket 
npm i node_modules/@types/websocket

Then in our React main.tsx let’s write some code where we connect to the server and send a random message for testing:

import { useEffect, useState } from 'react'
import logo from './logo.svg'
import './App.css'

import * as WebSocket from "websocket"




function App() {

  useEffect(() => {
    console.log("in it")
    const socket = new WebSocket.w3cwebsocket('ws://localhost:8080/ws');

    socket.onopen = function () {
      socket.send("helloheee!")
      socket.onmessage = (msg: any) => {
        console.log(msg);
        console.log("we got msg..")
      };
    };
  }, []);


  const [count, setCount] = useState(0)

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>Hello Vite + React!</p>
        <p>
          <button type="button" onClick={() => setCount((count) => count + 1)}>
            count is: {count}
          </button>
        </p>
        <p>
          Edit <code>App.tsx</code> and save to test HMR updates.
        </p>
        <p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
          {' | '}
          <a
            className="App-link"
            href="https://vitejs.dev/guide/features.html"
            target="_blank"
            rel="noopener noreferrer"
          >
            Vite Docs
          </a>
        </p>
      </header>
    </div>
  )
}

export default App

Also worth noting, inside the main.tsx I removed the StrictMode elements

<React.StrictMode>

if I didn’t it would trigger the user effect twice for some reason. Anyway that’s it to get started fast with a web socket to start experimenting. Hope coding!