How to have ONE anonymous GraphQL mutation, but all the others secured

I am using the MongoDB GraphQL endpoint.
I’ve setup several custom functions as graphQL mutations.

  1. Register a new user
  2. Create a blog post
  3. Add a comment to a post ,…

Now I want to have the registration (1) available to everyone. Anonymously. But all the other mutations shall only be able for registered users.

How to I configure that in MongoDB GraphQL?

Can I use “Custom Function Authentication”? The UI sais “all requests to GraphQL must be authenticated”. Can I create an exception?

Thank you for any support or hints.

@Robert_Rackl1 ,

I would go the direction of having a “registration” api key and the module for registration will use this key to do any query/registration mutation. Any other calls will require a user authentication…

Does that sound good to you?

Thanks
Pavel

1 Like

Yes that sounds fine. Just one detail question. What do you mean by “module” ? As far as I can see there is only one MongoDB GraphQL endpoint in my mongodb atlas app that has ONE configuratioon for authentication.

I have another follow up questins: Ok let’s say I have a way how new user’s can register. The call something anonymously (eg. an HTTP endpoint).

=> Then how do I create a user in a MongoDB atlas function?

Use Case Flow

  1. Client App calls registration endpiont /register with custom static registration API key (a preconfigured JWT that’s hardcoded in the client app)
  2. Custom function does the registration (eg. store user’s metadata etc.)
  3. Custom function returns new JWT for this user. With this users email as “sub”.

But now the new user is still not registered as a user in MongoDB Atlas! How to do that??? The doc sais that a user will automatically be created once he makes a call with his JWT. https://www.mongodb.com/docs/atlas/app-services/users/create/

Found another related topic. Create/register user on backend with Realm function - #3 by Mohammed_Ramadan

Thee Pavel wrote: " there isn’t a registration process separate from the login process, you call the same function every time," Mmmhh ok, I have to look into that …

And here Register User in Web via Endpoint - #2 by nirinchev nirinchev mentions a not documented /register endpoint. Let’s see …

Hi @Robert_Rackl1 ,

I think there is an option to automatically create user upon login with thr correct credentials.

Let me know if that helps?

Thanks
pavel

Yes that seems to be the only way. It just feels a bit weired. It’s a workaround.

Resgistration and login are two different things. For example at registration the client normally passes more information, such as additonal metadata. For login the client only passis the most basic data (eg. username and password, no additonal name, postal adress or mobile phone number).

Would be nice if MongoDB Atlas would offer a way to actually register a user. (of course this depends on the authentication provide that you use.)

Ok, I got it working. Maybe a workaround. But it does work. HEre is my source code:

/**
 * Create a new team  and a mongoDB Atlas User
 * @param {Object} GraphQL TeamInsertInput { teamName admins { name email mobilephone } }
 * @return {Object} error or { team user jwt }
 *
 * This function uses some `config` variables read from mongodb app values
 */
exports = async (newTeam) => {
  console.log("CreateNewTeam (context.user", JSON.stringify(context.user))
  
  // ===== Insert newTeam into DB
  var collection = context.services.get("mongodb-atlas").db(config.dbName).collection(config.collection)
  let insertResult = await collection.insertOne(newTeam)

  // ===== Query team (returned document contains _id !)
  let team = await collection.findOne({_id: insertResult.insertedId})
	
  // ====== Create a **new** JWT for the new user
  // .... some code with https://www.mongodb.com/docs/atlas/app-services/functions/globals/#std-label-function-utils-jwt
 // Keep in mind that the JWT must exactly match you configuration !
 // eg. issuer ("iss" claim) must be set correctly if you configured that
 // and of course use the correct secret to sign the key
 let token = /* ... create JWT ... *//

  // Make an authenticated call to Atlas App, so that MongoDB Atlas User is created (automatically)
  // https://www.mongodb.com/docs/atlas/app-services/users/create/
  let postRes = await context.http.post({ 
    url: config.API_URL,
    headers: {
      // THIS IS IMPORTANT !!! Need to set the "jwtTokenString" header!
      //. "Authentication: Bearer ....."   DOES NOT WORK HERE !!
      "jwtTokenString": [ token ]    
    },
    body: { query: "{ team { _id teamName} }" },   // just query anything
    encodeBodyAsJSON: true
  })
  // The response body is a BSON.Binary object. Parse it and return.
  console.log("response of post: "+ JSON.stringify(postRes))

  //  Now the new user has also been created in MongoDB Atlas internal user list. 

  return {
    team: team,
    user: team.admins[0],
    jwt: token
  }
}


1 Like

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