Validating Cotter's Identity Token
Cotter's token includes the user's email or phone number, your API_KEY_ID, and a signature . Here's the full token object:
1
"token": {
2
"identifier_id": "e8a47aff-f520-4b8d-952b-79d36d10fb3e",
3
"expire_at": "1588849208",
4
"identifier": "+12345678910", // user's email or phone
5
"identifier_type": "PHONE",
6
"receiver": "<YOUR API KEY ID>",
7
"signature": "21P6mXSF2x357kZGkEMQTRTn3r...",
8
"timestamp": "1586257208" // unix Timestamp
9
}
Copied!
Check that the receiver contains your API_KEY_ID

Verifying the Signature

The signature ensures that this token comes from Cotter's server:
  • Signature algorithm: ed25519
  • Cotter's Public Key: qqOaiQGjGsxBMgI5rdAasaACRiJthOqadmefjY5mS/c=
  • Signed Message:
1
{token.identifier}{token.identifier_type}{token.receiver}{token.expire_at}
Copied!
Note that there is no space and no {} in the message. It's all just 1 long string. ex. +1234567890PHONEaaf7319d-8f91-4752-a23f-c43ba862d5481582679175

Example

JavaScript
React Native
Go
Python
1
​
2
var cotter = require("cotter-token-js");
3
​
4
var cotterIdentity = new cotter.CotterIdentity(token);
5
var valid = cotterIdentity.validate()
Copied!
1
import { Cotter } from 'react-native-cotter';
2
​
3
var valid = Cotter.validateIdentityResponse(response.token);
Copied!
1
// https://golang.org/pkg/crypto/ed25519/
2
func Verify(publicKey string, signStr string, args ...string) (bool, error) {
3
str := []byte(strings.Join(args, ""))
4
fmt.Println(strings.Join(args, ""))
5
pubKey, err := base64.StdEncoding.DecodeString(publicKey)
6
if err != nil {
7
return false, responses.NewError("Fail verifying signature decoding pubkey", err)
8
}
9
signature, err := base64.StdEncoding.DecodeString(signStr)
10
if err != nil {
11
return false, responses.NewError("Fail verifying signature decoding signature", err)
12
}
13
valid := ed25519.Verify(pubKey, str, signature)
14
return valid, nil
15
}
16
​
17
// Usage
18
valid, err := Verify(enum.CotterPublicKey, token.Signature, token.Identifier, string(token.IdentifierType), token.ReceiverID.String(), token.ExpireAt)
19
​
Copied!
1
# https://pynacl.readthedocs.io/en/stable/signing/
2
import binascii
3
import nacl.signing
4
import nacl.encoding
5
​
6
pub64 = "qqOaiQGjGsxBMgI5rdAasaACRiJthOqadmefjY5mS/c="
7
signatureB64 = token["signature"]
8
message = token["identifier"] + token["identifier_type"] + token["receiver"] + token["expire_at"]
9
​
10
signb = binascii.a2b_base64(signatureB64)
11
msgb = str.encode(message)
12
​
13
verify_key = nacl.signing.VerifyKey(pub64, encoder=nacl.encoding.Base64Encoder)
14
verify_key.verify(msgb, signb)
Copied!
Libraries for ed25519 algorithm are available in Javascript, Golang, Python and other languages.
Last modified 1yr ago
Copy link