# Alternative email as authentication

**URL:** <https://community.parseplatform.org/t/alternative-email-as-authentication/191>\
**Category:** Parse Server 📡\
**Tags:** authentication, email\
**Created:** [April 22, 2020, 2:05am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191 "2020-04-22T02:05:15Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 22, 2020, 2:05am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/1 "2020-04-22T02:05:15Z")

</div>

I have this scenario where users are expected to fill up an alternative email address and use that to authenticate user but I don’t know how or if there is an existing API that can be used to do that. I would like to know it.

---

<div class="post-metadata">

**Author:** ![Moumouls](https://community.parseplatform.org/user_avatar/community.parseplatform.org/moumouls/32/332_2.png) [@Moumouls](https://community.parseplatform.org/u/Moumouls)\
**Post date:** [April 22, 2020, 8:17am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/2 "2020-04-22T08:17:58Z")

</div>

You probably need to design a custom auth:  
Notice that here i’m using GraphQL API for internal calls, i’m also using Typescript

```auto
// Custom Email Auth module
export const CustomEmailAuth = {
	async validateAuthData(authData: CustomAuthEmailInput) {

        //authData.id is email, need to keep this name for Parse Server auth engine
		if (authData.id && authData.password) {
            // Auth data should be already set on the user
			const { users } = await client.findUsersByCustomAuth({ email: authData.id })

			if (users.edges?.length === 1 && users.edges[0] && users.edges[0].node) {
				const user = users.edges[0].node
				// Additional safety check
				if (
					user.authData?.customEmail?.id === authData.id &&
					user.authData?.customEmail?.password &&
					user.authData.customEmail.password ===
						SHA512(authData.password).toString()
				) {
					return
				}
			}
		}
                // Always throw by default for security purpose
		throw new Error('Invalid authData')
	},

	async validateAppId() {
		return true
	},
}

```

```auto
// On the Parse Server Config
auth: {
    customEmail: {
        module: CustomEmailAuth,
    },
},

```

```auto
# The query used to find the user
query findUsersByCustomAuth($email: Any!) {
    users(where: { authData: { equalTo: { key: "customEmail.id", value: $email } } }, first: 2) {
      edges {
        node {
          id
          username
          authData {
            customEmail {
              id
              password
            }
          }
        }
      }
    }
  }

```

---

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 22, 2020, 8:41am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/3 "2020-04-22T08:41:19Z")

</div>

Sorry I should have stated my tools first and made clear of the statement of what I’m trying to do. I’m not familiar with GraphQL, I only used, NodeJS Server and JS-SDK.

Let’s say, A user signed up with email and password. The username is what the user inputted as their email. Aside from it was personal info, and then `alternativeEmail` field as part of `_User` class name.

The next time, that user logged in, he decided to use his alternative email address to authenticate.

How will I be able to do that?

Based on your solution, I need to setup a custom authentication (though I need to study custom auth first), and in the client, I need to provide an AuthProvider and use `linkWith`?

---

<div class="post-metadata">

**Author:** ![Moumouls](https://community.parseplatform.org/user_avatar/community.parseplatform.org/moumouls/32/332_2.png) [@Moumouls](https://community.parseplatform.org/u/Moumouls)\
**Post date:** [April 22, 2020, 9:04am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/4 "2020-04-22T09:04:25Z")

</div>

Yes custom auth + linkWith, parse server donnot support alternative emails for auth

---

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 22, 2020, 9:06am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/5 "2020-04-22T09:06:49Z")

</div>

Upon looking at UsersRoute of PS, I just saw how they handle querying for email, username, and password comparison using crypto. I’ll try to mimic haw they did it.

---

<div class="post-metadata">

**Author:** ![uzaysan](https://community.parseplatform.org/user_avatar/community.parseplatform.org/uzaysan/32/59_2.png) [@uzaysan](https://community.parseplatform.org/u/uzaysan)\
**Post date:** [April 22, 2020, 11:57am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/6 "2020-04-22T11:57:30Z")

</div>

You can use this simple cloud code:

```
Parse.Cloud.define("loginWithAlternativeEmail", async (request) => {

  var alternativeEmail = request.params.email;

  var pass = request.params.pass;
  
  if(!alternativeEmail||!pass){
    throw "error";
  }

  var userQuery = new Parse.Query(Parse.User);
  userQuery.equalTo("alternativeEmail",alternativeEmail);
  userQuery.limit(1);
  var result = await userQuery.find();
  if(result.length<1){
    throw "loginError";
  }

  var tempUser = result[0];
  var user = await Parse.User.logIn(tempUser.get("username"),pass);
  return user.getSessionToken();
  

});

```

Then use become method in javascript using sessionToken that cloud code returned.

`Parse.User.become(token);`

---

<div class="post-metadata">

**Author:** ![Moumouls](https://community.parseplatform.org/user_avatar/community.parseplatform.org/moumouls/32/332_2.png) [@Moumouls](https://community.parseplatform.org/u/Moumouls)\
**Post date:** [April 22, 2020, 12:05pm UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/7 "2020-04-22T12:05:47Z")

</div>

Yes more affordable solution ! Thanks @uzaysan

---

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 29, 2020, 8:11am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/8 "2020-04-29T08:11:31Z")

</div>

Thanks to both of you. @uzaysan I was wondering, is there any security risk like checking the number of attempts and so on?

---

<div class="post-metadata">

**Author:** ![uzaysan](https://community.parseplatform.org/user_avatar/community.parseplatform.org/uzaysan/32/59_2.png) [@uzaysan](https://community.parseplatform.org/u/uzaysan)\
**Post date:** [April 29, 2020, 8:25am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/9 "2020-04-29T08:25:05Z")

</div>

I don’t think failed attemps would be security risk. Parse server itself comes with unlimited login try by default. But if you wanna restrict login after x times fail You can use `accountLockout` policy. More information of parse parameters can be found [here](https://parseplatform.org/parse-server/api/4.2.0/ParseServerOptions.html)

---

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 29, 2020, 8:27am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/10 "2020-04-29T08:27:56Z")

</div>

Is there a way to pull that from parse server so that I will be able to re-use that kind of logic?

---

<div class="post-metadata">

**Author:** ![uzaysan](https://community.parseplatform.org/user_avatar/community.parseplatform.org/uzaysan/32/59_2.png) [@uzaysan](https://community.parseplatform.org/u/uzaysan)\
**Post date:** [April 29, 2020, 8:30am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/11 "2020-04-29T08:30:17Z")

</div>

I didn’t understand what you said. English is not my native language. Can you explain a little simple?

---

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 29, 2020, 8:33am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/12 "2020-04-29T08:33:42Z")

</div>

So do I 😆

I want to know if there is a way to re-use the logic of account policy from parse server instead of creating your own account policy?

---

<div class="post-metadata">

**Author:** ![uzaysan](https://community.parseplatform.org/user_avatar/community.parseplatform.org/uzaysan/32/59_2.png) [@uzaysan](https://community.parseplatform.org/u/uzaysan)\
**Post date:** [April 29, 2020, 8:36am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/13 "2020-04-29T08:36:03Z")

</div>

So I guess you are talking about the code I posted above. It doesn’t change parse server account policy. It uses it. So normal account login/register should be work fine. Its just cloud code. It doesn’t change parse server behaviour.

---

<div class="post-metadata">

**Author:** ![JeromeDeLeon](https://community.parseplatform.org/user_avatar/community.parseplatform.org/jeromedeleon/32/84_2.png) [@JeromeDeLeon](https://community.parseplatform.org/u/JeromeDeLeon)\
**Post date:** [April 29, 2020, 8:37am UTC](https://community.parseplatform.org/t/alternative-email-as-authentication/191/14 "2020-04-29T08:37:36Z")

</div>

Oh I see. Thanks a lot.
