Q:

fsharp jwt

module JsonWebToken =
    open System
    open System.Text
    open System.Text.RegularExpressions
    open System.Security.Cryptography
    let replace (oldVal: string) (newVal: string) = fun (s: string) -> s.Replace(oldVal, newVal)
    let minify = 
        let regex = Regex("(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", RegexOptions.Compiled|||RegexOptions.CultureInvariant)
        fun s ->
            regex.Replace(s, "$1")
    let base64UrlEncode bytes =
        Convert.ToBase64String(bytes) |> replace "+" "-" |> replace "/" "_" |> replace "=" ""
    type IJwtAuthority =
        inherit IDisposable
        abstract member IssueToken: header:string -> payload:string -> string
        abstract member VerifyToken: string -> bool
    let newJwtAuthority (initAlg: byte array -> HMAC) key =
        let alg = initAlg(key)
        let encode = minify >> Encoding.UTF8.GetBytes >> base64UrlEncode
        let issue header payload =
            let parts = [header; payload] |> List.map encode |> String.concat "."
            let signature = parts |> Encoding.UTF8.GetBytes |> alg.ComputeHash |> base64UrlEncode
            [parts; signature] |> String.concat "."
        let verify (token: string) =
            let secondDot = token.LastIndexOf(".")
            let parts = token.Substring(0, secondDot)
            let signature = token.Substring(secondDot + 1)
            (parts |> Encoding.UTF8.GetBytes |> alg.ComputeHash |> base64UrlEncode) = signature

        {
            new IJwtAuthority with
                member this.IssueToken header payload = issue header payload
                member this.VerifyToken token = verify token
                member this.Dispose() = alg.Dispose()
        }

open System.Text
open System.Security.Cryptography
open JsonWebToken
let header = 
    """{
        "alg": "HS256",
        "typ": "JWT"
    }"""
let payload = 
    """{
        "sub": "1234567890",
        "name": "John Doe",
        "admin": true
    }"""
let encodedSecret = "secret" |> Encoding.UTF8.GetBytes
let testAuth = newJwtAuthority (fun key -> new HMACSHA256(key) :> HMAC) encodedSecret
let token = testAuth.IssueToken header payload
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
testAuth.VerifyToken token
testAuth.Dispose()
-1

New to Communities?

Join the community