3 people like it.
Like the snippet!
Creating and validating JWTs in just 35 lines of F# code.
A fast and lightweight json web token (JWT) creator and validator.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
|
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()
|
namespace System
namespace System.Text
namespace System.Text.RegularExpressions
namespace System.Security
namespace System.Security.Cryptography
val replace : oldVal:string -> newVal:string -> s:string -> string
Full name: Script.JsonWebToken.replace
val oldVal : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
val newVal : string
val s : string
String.Replace(oldValue: string, newValue: string) : string
String.Replace(oldChar: char, newChar: char) : string
val minify : (string -> string)
Full name: Script.JsonWebToken.minify
val regex : Regex
Multiple items
type Regex =
new : pattern:string -> Regex + 1 overload
member GetGroupNames : unit -> string[]
member GetGroupNumbers : unit -> int[]
member GroupNameFromNumber : i:int -> string
member GroupNumberFromName : name:string -> int
member IsMatch : input:string -> bool + 1 overload
member Match : input:string -> Match + 2 overloads
member Matches : input:string -> MatchCollection + 1 overload
member Options : RegexOptions
member Replace : input:string * replacement:string -> string + 5 overloads
...
Full name: System.Text.RegularExpressions.Regex
--------------------
Regex(pattern: string) : unit
Regex(pattern: string, options: RegexOptions) : unit
type RegexOptions =
| None = 0
| IgnoreCase = 1
| Multiline = 2
| ExplicitCapture = 4
| Compiled = 8
| Singleline = 16
| IgnorePatternWhitespace = 32
| RightToLeft = 64
| ECMAScript = 256
| CultureInvariant = 512
Full name: System.Text.RegularExpressions.RegexOptions
field RegexOptions.Compiled = 8
field RegexOptions.CultureInvariant = 512
Regex.Replace(input: string, evaluator: MatchEvaluator) : string
Regex.Replace(input: string, replacement: string) : string
Regex.Replace(input: string, evaluator: MatchEvaluator, count: int) : string
Regex.Replace(input: string, replacement: string, count: int) : string
Regex.Replace(input: string, evaluator: MatchEvaluator, count: int, startat: int) : string
Regex.Replace(input: string, replacement: string, count: int, startat: int) : string
val base64UrlEncode : bytes:byte [] -> string
Full name: Script.JsonWebToken.base64UrlEncode
val bytes : byte []
type Convert =
static val DBNull : obj
static member ChangeType : value:obj * typeCode:TypeCode -> obj + 3 overloads
static member FromBase64CharArray : inArray:char[] * offset:int * length:int -> byte[]
static member FromBase64String : s:string -> byte[]
static member GetTypeCode : value:obj -> TypeCode
static member IsDBNull : value:obj -> bool
static member ToBase64CharArray : inArray:byte[] * offsetIn:int * length:int * outArray:char[] * offsetOut:int -> int + 1 overload
static member ToBase64String : inArray:byte[] -> string + 3 overloads
static member ToBoolean : value:obj -> bool + 17 overloads
static member ToByte : value:obj -> byte + 18 overloads
...
Full name: System.Convert
Convert.ToBase64String(inArray: byte []) : string
Convert.ToBase64String(inArray: byte [], options: Base64FormattingOptions) : string
Convert.ToBase64String(inArray: byte [], offset: int, length: int) : string
Convert.ToBase64String(inArray: byte [], offset: int, length: int, options: Base64FormattingOptions) : string
type IJwtAuthority =
interface
inherit IDisposable
abstract member IssueToken : header:string -> payload:string -> string
abstract member VerifyToken : string -> bool
end
Full name: Script.JsonWebToken.IJwtAuthority
type IDisposable =
member Dispose : unit -> unit
Full name: System.IDisposable
abstract member IJwtAuthority.IssueToken : header:string -> payload:string -> string
Full name: Script.JsonWebToken.IJwtAuthority.IssueToken
abstract member IJwtAuthority.VerifyToken : string -> bool
Full name: Script.JsonWebToken.IJwtAuthority.VerifyToken
type bool = Boolean
Full name: Microsoft.FSharp.Core.bool
val newJwtAuthority : initAlg:(byte array -> HMAC) -> key:byte array -> IJwtAuthority
Full name: Script.JsonWebToken.newJwtAuthority
val initAlg : (byte array -> HMAC)
Multiple items
val byte : value:'T -> byte (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.byte
--------------------
type byte = Byte
Full name: Microsoft.FSharp.Core.byte
type 'T array = 'T []
Full name: Microsoft.FSharp.Core.array<_>
type HMAC =
inherit KeyedHashAlgorithm
member HashName : string with get, set
member Initialize : unit -> unit
member Key : byte[] with get, set
static member Create : unit -> HMAC + 1 overload
Full name: System.Security.Cryptography.HMAC
val key : byte array
val alg : HMAC
val encode : (string -> string)
type Encoding =
member BodyName : string
member Clone : unit -> obj
member CodePage : int
member DecoderFallback : DecoderFallback with get, set
member EncoderFallback : EncoderFallback with get, set
member EncodingName : string
member Equals : value:obj -> bool
member GetByteCount : chars:char[] -> int + 3 overloads
member GetBytes : chars:char[] -> byte[] + 5 overloads
member GetCharCount : bytes:byte[] -> int + 2 overloads
...
Full name: System.Text.Encoding
property Encoding.UTF8: Encoding
Encoding.GetBytes(s: string) : byte []
Encoding.GetBytes(chars: char []) : byte []
Encoding.GetBytes(chars: char [], index: int, count: int) : byte []
Encoding.GetBytes(chars: nativeptr<char>, charCount: int, bytes: nativeptr<byte>, byteCount: int) : int
Encoding.GetBytes(s: string, charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
Encoding.GetBytes(chars: char [], charIndex: int, charCount: int, bytes: byte [], byteIndex: int) : int
val issue : (string -> string -> string)
val header : string
val payload : string
val parts : string
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Encoding) : unit
val concat : sep:string -> strings:seq<string> -> string
Full name: Microsoft.FSharp.Core.String.concat
val signature : string
HashAlgorithm.ComputeHash(buffer: byte []) : byte []
HashAlgorithm.ComputeHash(inputStream: IO.Stream) : byte []
HashAlgorithm.ComputeHash(buffer: byte [], offset: int, count: int) : byte []
val verify : (string -> bool)
val token : string
val secondDot : int
String.LastIndexOf(value: string) : int
String.LastIndexOf(value: char) : int
String.LastIndexOf(value: string, comparisonType: StringComparison) : int
String.LastIndexOf(value: string, startIndex: int) : int
String.LastIndexOf(value: char, startIndex: int) : int
String.LastIndexOf(value: string, startIndex: int, comparisonType: StringComparison) : int
String.LastIndexOf(value: string, startIndex: int, count: int) : int
String.LastIndexOf(value: char, startIndex: int, count: int) : int
String.LastIndexOf(value: string, startIndex: int, count: int, comparisonType: StringComparison) : int
String.Substring(startIndex: int) : string
String.Substring(startIndex: int, length: int) : string
val this : IJwtAuthority
abstract member IJwtAuthority.IssueToken : header:string -> payload:string -> string
abstract member IJwtAuthority.VerifyToken : string -> bool
IDisposable.Dispose() : unit
HashAlgorithm.Dispose() : unit
module JsonWebToken
from Script
val header : string
Full name: Script.header
val payload : string
Full name: Script.payload
val encodedSecret : byte []
Full name: Script.encodedSecret
val testAuth : IJwtAuthority
Full name: Script.testAuth
Multiple items
type HMACSHA256 =
inherit HMAC
new : unit -> HMACSHA256 + 1 overload
Full name: System.Security.Cryptography.HMACSHA256
--------------------
HMACSHA256() : unit
HMACSHA256(key: byte []) : unit
val token : string
Full name: Script.token
System.IDisposable.Dispose() : unit
More information