Need help understanding User Verification through Email Link

Hey All,

I’ve been trying to research how to verify/validate users through an email link using just Apollo Server 3 without libraries like apollo-server-express. I am fairly new to creating full-stack websites with Apollo and GraphQL so I’m struggling finding parallels with Express endpoints and routes/paths. I apologies if I explain this poorly but I believe I have a basic understanding of how to create a token and a standard way to store a token in cache (currently looking into redis-cache)… but I’m struggling with how to create a link that somehow can connect to Apollo Server and verify a token/user and then redirect them to the home page logged in. Right now I’m in the research phase so I don’t have code to look at. I’m just trying to gain the understanding of how this would or should happen in Apollo Server.

I thank everyone for their time and patience!
Haru

This is actually very simple if you think about it. Look at the REST API. What do you do if you want to call a list of users? You call

GET https://example.com/api/users

And then you get some kind of JSON with a list of users. And when do you want to call a specific user?

GET https://example.com/api/users/5

And you get a single user object in JSON format. How does this work in graphql? Similar but instead of calling separate routes you have a single endpoint and you just prepare the query for that endpoint just like you would do for example in SQL. If you want to fetch data you use queries and when you want to modify data you use mutations. So the simplest query would be:

{
    users {
        id
        name
        surname
        profile_pic
    }
}

And you get a response similar to when you would call https://example.com/api/users

That’s a general idea.

Now when it comes to authentication it’s also the same. How do you generally authenticate REST API written using express? You generate some sort of token and send it to the user and then the user sends that token with each request to authenticate it. That’s the most basic example. You do something very similar in Apollo. And there is a very simple example you can check:

In short in your context function, you check if the header or cookie of the request contains a token, verify that token, and load the user assigned to it. And from that moment user is available in the context object. It’s the same context that also contains data sources and other things.

Now, when it comes to token storage there is really no need to use REDIS. Just use your regular database. And manually check the expiration date (if there is one). You can also run a query that delete expired token by simply comparing expiration dates with a current date.

There is also a way to use it without ANY database by using JWT. You can read about JWT tokens here:

https://jwt.io/

In short, JWT is a token that can contain data, expiration date, and other useful stuff.

When a user creates an account or changes a password you re-generate the certificate/passphrase you use to generate and verify the token. You do that to make sure that if a user’s token leaks (like when his device gets stolen) and he changes the password on the website or you detect a leak inside your app - you just regenerate everyone’s certificate/passphrase and it’s all good because old tokens will not be verified.

Why I’m saying that you do not need a database? Because token authenticity can be verified - you do not need to store them anywhere.

When he authenticates, you send that token to the client app and the client app uses the token to authenticate every request. When apollo receives JWT, you decode it, you pull the user ID if present. And then you verify the token using the certificate/passphrase assigned to the user.

If authentication is successful, you can put that user data in the context and you should know what to do from here.

1 Like

Thanks for the response! So how would one go about being able to create a URL link that could be sent via email to validate/finish registering a user after registration? Where/how in Apollo GraphQL would you create a page/route/path that could verify the token and approve the user to continue logging in as a validated user upon clicking a link? Is it simply done through resolvers on the server and called from Apollo Client? I think my biggest confusion is how the URL link can call a function to validate a user. There seems to be a million nodejs/express examples of how to do this but so far I haven’t really found one for Apollo Server so I’m wondering if Apollo makes this super easy or has a better/different way of accomplishing this.

As a little background I have a bit of experience creating static websites with HTML CSS JS and PHP but I really fell for GraphQL when learning how to create react apps and Apollo made things super easy so most of my knowledge comes from trial and error! So I might be missing an extremely simple point so thank you for your explanations and patience!

When user creates an account you mark him in database as not verified and you generate some sort of unique verification token. Then you send URL to your app containing this token via email. When user click on email, it loads your client app and client app send token to backed. And you mark user who has this token assigned as verified.

In graphql when you modify data, you use mutations. So that is how you should do it. Once he clicks on the link, you get token from the url and you run a mutation on apollo server with that token as parameter.

Reason why there is million examples of how to do it in express is because there is no standard way of doing it.

The only difference is that in express you would do post/put/patch request to REST API with the token and you would write logic that mark user with that token as verified and in graphql instead of post/put/patch you do a mutation.

It’s really that simple. Queries fetch data. Mutations modify data.

1 Like

This really helps so much. Thank You!