Migrating JWT provider from Realm Cloud to MongoDB

I had JWT auth set up back in the Realm Cloud days. Now I’m migrating to MongoDB and hit a snag logging into realm, the error is invalid custom auth token: valid UID required (between 1 and 128 characters)

My JWT provider is a Firebase function:

const functions = require('firebase-functions');
const jwt = require('jsonwebtoken');
const fs = require('fs');
const key = fs.readFileSync('privatekey.pem');
exports.myAuthFunction = functions.https.onCall((data, context) => {
    const uid = context.auth.uid;
    const payload = { userId: uid };
    const token = jwt.sign(payload, { key: key, passphrase: "redacted" }, { algorithm: 'RS256'});
    return { token:token }
});

I’m calling that in my app like so:

    func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {
        guard let fireUser = authDataResult?.user else { return }

        Functions.functions().httpsCallable("authenticationfunc").call { [weak self] result, _ in
            guard let dict = result?.data as? [String: Any] else { return }
            guard let token = dict["token"] as? String else { return }

            self?.gotJWT(jwt: token)
        }
    }

    func gotJWT(jwt: String) {
        let credentials = Credentials.jwt(token: jwt)
        app.login(credentials: credentials) { [weak self] (result) in
            switch result {
            case .failure(let error):
                print("Login failed: \(error.localizedDescription)")
            case .success(let user):
                print("Successfully logged in as user \(user)")
            }
        }
    }

Should I be adding more fields to the payload? This guide makes it sound like I need to add aud field, etc, https://www.mongodb.com/docs/atlas/app-services/tutorial/jwt/#payload

To answer my question - yes those fields are required. If anyone else runs into this, here’s my cloud function:

const functions = require('firebase-functions');
const jwt = require('jsonwebtoken');
const fs = require('fs');
const key = fs.readFileSync('privatekey.pem');
exports.myAuthFunction = functions.https.onCall((data, context) => {
    const uid = context.auth.uid;
    const subject = context.auth.token.email;
    const userName = context.auth.token.name;
    const audience = "redacted";
    const expires = Math.floor(Date.now() / 1000) + (very secure number of seconds);
    const payload = { userId: uid, sub: subject, name: userName, aud: audience, exp: expires };
    const token = jwt.sign(payload, { key: key, passphrase: "redacted" }, { algorithm: 'RS256'});
    return { token:token }
});

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.