Problems authenticating using JWT token

Has anyone been able to login to MongoDB Realm using a JWT token generated by Firebase? I believe I have everything set up correctly in RealmUI: enabled the Custom JWT Authentication, specified the algorithm (RS256), entered my public key. In my code I have Firebase generate the token which has the aud, sub, exp, and iat values set in the payload. I create the credentials and then try to login:

let credentials = RLMAppCredentials.init(jwt: token)
self.realmApp!.login(withCredential: credentials, completion: { (syncUser, error) in
...
}

The login fails and the error I get back is

Error Domain=realm::app::ServiceError Code=2 “authentication via ‘custom-token’ is unsupported” UserInfo={NSLocalizedDescription=authentication via ‘custom-token’ is unsupported, realm::app::ServiceError=InvalidSession}

I have no idea why the server thinks it’s a custom token.

@Nina_Friend Can you share your custom auth code please?

I assume you mean my Google function for getting the token. Here it is:

const jwt = require('jsonwebtoken');
const fs = require('fs');
const key = fs.readFileSync("jwtRS256.key");
exports.realmFirebaseAuth = functions.https.onCall((data, context) => {    
    const uid = context.auth.uid; 
    const payload = { };    
    const token = jwt.sign(payload, { key: key, passphrase: "<My PassPhrase>" }, { algorithm: 'RS256', subject: uid, audience: "<Realm App Id>", expiresIn: "1d"});    
    return { token:token };
});

@Nina_Friend I was trying to confirm your JWK configuration on the Realm custom auth side because this should be supported - https://stackoverflow.com/questions/56576302/is-it-possible-to-use-firebase-signinwithemailandpassword-in-stitch-custom-authe

What version of the Realm SDK are you using?

My SDK in 10.0.0-beta.2.

@Nina_Friend What does your Custom JWT configuration looks like in the Realm Cloud UI ?

I just tried my code again. I had the wrong Realm App Id being passed to jwt.sign. I fixed that but now I’m getting a different error when I call realmApp.login:

Error Domain=realm::app::ServiceError Code=47 “Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key” UserInfo={NSLocalizedDescription=Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key, realm::app::ServiceError=AuthError}

Here is my set up in the Realm UI:

I had authentication working with the Realm Cloud Platform. I got it going a year ago using the detailed instructions that were on the old Realm website. It would be really helpful to have step-by-step instructions like that again for the MongoDB platform.

This is a server side error not a client one. I would guess that the JWT is being generated incorrectly

Hi! Did you get this resolved? I wrote the guide for the Realm Cloud Function and I am using Firebase with MongoDb Realm now.

In MongoDb Realm there is no need for the cloud function to authenticate. You can pass the firebase token from firebaseUser.getIdToken() and pass that directly into MongoDbRealm JWT authentication. All you need to do is to configure the JWT authentication to use https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com as JWK url and specify your firebase project name as audience, then you are done.

As a bonus, authentication will be faster since you skip the roundtrip to your cloud function :wink:

I would check the content of the JWT token in https://jwt.io. Basically you need to make sure that it has aud property with the realm app id, a sub property with the user’s email, an exp with the expiration date of the token, and possibly some user_data metadata with at least an email or a name so that it can set the name in the User’s table, finally include an iat property with time of creation.

Something like this

{
    "aud": "realmtest-ufdbt",
    "sub": “richard@cosync.io”,
    "exp": 1596288789,
    “user_data": {
          "email": “richard@cosync.io”
     },
    "iat": 1596245589
}

We are working on a JWT authenticator for Realm, and got the JWT authentication to work with the new MongoDB Realm, so I know it is possible.

We investigated this issue and it turns out we are not processing the Firebase tokens with the correct crypto format - we are looking to fix that now. We should be able to check the type of the key after parsing the provided public key PEM and then choose the correct x509 parsing function.

in the meantime, I just tried this using an openssl-generated keypair and it works fine, so you may want to try that out

// generate a public and private RSA key pair
openssl genrsa -out private.pem 4096

// export the RSA public key to PEM
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

That is weird… I got the firebase auth working in my app using the mobile SDKs? Data was synced fine, but I was only using a public, read only Realm. But this isn’t supposed to be working?