Link to home
Start Free TrialLog in
Avatar of Lorna Chandler
Lorna Chandler

asked on

How to limit user registration to a specific set of domains?

Is there a way to limit registration to certain email domains?

//email validation / only allow certain domains to register
      $allowed_domains = array("email.com", "outlook.com", "testmail.com");
    $email_domain = array_pop(explode("@", $email));
   if(!in_array($email_domain, $allowed_domains)) {
    //Not an authorized email
   }

this code isn't working, it allows all email addresses to register.
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Firstly, how to fix the code you have.
The problem is you are passing explode(...) as a parameter to array_pop() - PHP won't like this as you are passing a value instead of a reference. Rather do this
$email = "test@testmail.com";
$allowed_domains = array("email.com", "outlook.com", "testmail.com");
$parts = explode("@", $email);
$email_domain = array_pop($parts);
if(!in_array($email_domain, $allowed_domains)) {
	echo "Not Authed";
}

Open in new window


Next, you can also achieve this with preg_match()
$pattern="/email\.com|outlook\.com|testmail\.com/";
if (preg_match($pattern, $email, $matches)) {
	echo "Yup";
}
else {
	echo "Nope";
}

Open in new window

You can create the pattern from your array of allowable names
$pattern = "/" . implode("|", $allowed_domains) . "/";

Open in new window


Which to use? The first one runs around 2.5 times faster than the second, so it is probably he one to go for. preg_match is very versatile so if there are other validations you nee to do then it might be a better option.

Either way make sure you lower case your email address before doing either using strtolower()
$email = strtolower($email);

Open in new window

This will ensure that you don't get emails rejected because someone entered capital letters.
Avatar of Lorna Chandler
Lorna Chandler

ASKER

the first one changed the email address to test@testemail.com

on the preg_match is there someway I should say email validation or something right now it is just letting any email through....
What's the rest of the code look like? Right now, all we see is a PHP comment:
//Not an authorized email
...but what code do you have that actually tries to reject the attempt?
right now I don't have any other code to block the attempt... all I have is the
//email validation / only allow certain domains to register
      $allowed_domains = array("outlook.com", "email.com", "gmail.com");
    $email_domain = array_pop(explode("@", $email));
   if(!in_array($email_domain, $allowed_domains)) {
    //Not an authorized email
   }

I also tried this

//allow only certain domains to register
                        $email = strtolower($email);
                        $pattern="/outlook\.com|gmail\.com|email\.com/";
                        if (!preg_match($pattern, $email, $matches)) {
                        echo "Authorized User";
            }

but I know on the preg_match I am missing some information for sure
Validating the email is only one part of your process. Once you've checked whether it's valid or not, you have to do something (or not) with the result i.e. process or don't process the registration. In very simple terms, you'd do something like so:

...
if(!in_array($email_domain, $allowed_domains)) {
    echo "Not Authed";
} else {
   // we're allowed to register
   DoTheRegistrationStuff()
}

It's up to you how you handle the differences between allowed and not allowed.
the first one changed the email address to test@testemail.com
That was my test code - you did not provide the code where you set the email address variable so you should remove that from my code.

The key bit was to fix your code with respect to lines 3 and 4 of my first listing.

Always post the code of what you have tried so we can see what you are doing.

The code I posted above does work - if you implement on your side then post your implementation so we can check it for you.
// email validation only allow certain domains to register
    $email = strtolower($email);
      $allowed_domains = array("something.com", "email.com", "somethingelse.com");
      $parts = explode("@", $email);
      $email_domain = array_pop($parts);
      if(!in_array($email_domain, $allowed_domains)) {
      echo "Not Authorized";

any email address can still register...

this code also lets anyone register
// email validation only allow certain domains to register
    $email = strtolower($email);
      if(!in_array($email_domain, $allowed_domains)) {
      echo "Not Authed";
      
      }else{
      //we're allowed to register
      $allowed_domains = array("matmgt.com", "oeg.com", "materialmanagement.com");
      $parts = explode("@", $email);
      $email_domain = array_pop($parts);}
Lorna. Take a slow read through the code you've posted. It just doesn't make any sense:

// email validation only allow certain domains to register
$email = strtolower($email);
if(!in_array($email_domain, $allowed_domains)) {
    echo "Not Authed";
}else{
    //we're allowed to register
    $allowed_domains = array("matmgt.com", "oeg.com", "materialmanagement.com");
    $parts = explode("@", $email);
    $email_domain = array_pop($parts);} 

Open in new window

Your basic logic is failing. You check if a domain is allowed and if it is you check the domain!

You're still only showing us part of your code, so we can't help you. What exactly do you mean by 'able to register'. What code do you have in place that handles that - where is it called.

The logic here should be straight forward.

if (domain is allowed to register) {
    // register them
} else {
    // don't register them
}
here are the pages that create the signup page
signup.php
utilities.php
Hey Lorna,

You don't seem to have any code in your pages that as been discussed here.

What you probably need to do is add a new function to your utilities.php file. Something like this:

function check_email_domain($emailAddress, $allowedDomains) {
	$form_errors = array();
	$parts = explode("@", $emailAddress);
	$domain = array_pop($parts);
	// Check if the email is allowed
	if(!in_array($domain, $allowedomains)) {
		$form_errors[] = "Email Domain is not allowed";
	}
	
	return $form_errors;
}

Open in new window

And then in your signup.php script, make a call to it by adding it along with your other form checkers:

//email validation / merge the return data into form_error array
$form_errors = array_merge($form_errors, check_email($_POST));

// ADD THIS BIT
//domain validation
$allowedDomains = array("email.com", "outlook.com", "testmail.com");
$form_errors = array_merge($form_errors, check_email_domain($_POST['email'], $allowedDomains));

Open in new window

I know you don't give cut and paste options, I'm supposed to read them and change what I need. However on this I am not sure what exactly I am supposed to change.


when I fill the form out I get these errors:
Warning: array_merge(): Argument #2 is not an array in C:\xampp\htdocs\Admin_System\signup.php on line 24

Notice: Undefined variable: allowedDomains in C:\xampp\htdocs\Admin_System\signup.php on line 28

Notice: Undefined variable: allowedomains in C:\xampp\htdocs\Admin_System\resource\utilities.php on line 66

Warning: in_array() expects parameter 2 to be array, null given in C:\xampp\htdocs\Admin_System\resource\utilities.php on line 66

Warning: array_merge(): Argument #1 is not an array in C:\xampp\htdocs\Admin_System\signup.php on line 28
here are the codes again
utilities.php
signup.php
Hey Lorna,

In this instance I did give you a cut and paste solution - you just pasted the code into the wrong place. I gave you a function to paste into your utilities code, but you somehow managed to paste my function inside of another one !!

This is how the 2 functions should look:

function check_email($data){
    //initialize an array to store error messages
    $form_errors = array();
    $key = 'email';
    //check if the key email exist in data array
    if(array_key_exists($key, $data)){

        //check if the email field has a value
        if($_POST[$key] != null){

            // Remove all illegal characters from email
            $key = filter_var($key, FILTER_SANITIZE_EMAIL);

            //check if input is a valid email address
            if(filter_var($_POST[$key], FILTER_VALIDATE_EMAIL) === false){
                $form_errors[] = $key . " is not a valid email address";
            }
        }
    }
}

function check_email_domain($emailAddress, $allowedDomains) {
    $form_errors = array();
    $parts = explode("@", $emailAddress);
    $domain = array_pop($parts);
    // Check if the email is allowed
    if(!in_array($domain, $allowedomains)) {
        $form_errors[] = "Email Domain is not allowed";
    }
    return $form_errors;
}

Open in new window

If you give your code a proper structure (using indents and line-spacing) then you'll spot errors like this straight away.
when i cut and pasted your code it let me access with incomplete email and all different domains so I did so I added form errors under both function checks...
function check_email($data){
    //initialize an array to store error messages
    $form_errors = array();
    $key = 'email';
    //check if the key email exist in data array
    if(array_key_exists($key, $data)){

        //check if the email field has a value
        if($_POST[$key] != null){

            // Remove all illegal characters from email
            $key = filter_var($key, FILTER_SANITIZE_EMAIL);

            //check if input is a valid email address
            if(filter_var($_POST[$key], FILTER_VALIDATE_EMAIL) === false){
                $form_errors[] = $key . " is not a valid email address";
            }
        }
    }
	 return $form_errors;
}

function check_email_domain($emailAddress, $allowedDomains) {
    $form_errors = array();
    $parts = explode("@", $emailAddress);
    $domain = array_pop($parts);
    // Check if the email is allowed
    if(!in_array($domain, $allowedomains)) {
        $form_errors[] = "Email Domain is not allowed";
    }
    return $form_errors;
}

Open in new window

and I get these errors when I try a good domain or a bad domain...

Notice: Undefined variable: allowedDomains in C:\xampp\htdocs\Admin_System\signup.php on line 28

Notice: Undefined variable: allowedomains in C:\xampp\htdocs\Admin_System\resource\utilities.php on line 68

Warning: in_array() expects parameter 2 to be array, null given in C:\xampp\htdocs\Admin_System\resource\utilities.php on line 68
ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok I will spend some time learning error messages... that worked... I want to enroll in one of the cloud courses offered... do you have recomendation where I should start??
First up - please use code tags (I have added for you). Highlight code, then click the CODE button in the toolbar. Makes your posts easier to read.

Next, your code makes no sense. Let's look at it in detail

Line 12 - you are sanitizing a value ($key) that you set to a constant ('email' line 4)
You are passing in $data - checking if the key is in the $data array - but then you are checking $_POST - yet at no time do you actually use the value from $data.

The errors you posted refer to lines we cannot see. If you post error references be sure to post the code they relate to.

Aside: in your scripts you use the extract() function - don't do that. It is a potential security risk.

Some of your functions can be combined to make your code a bit neater. I took the liberty of re-coding some of the validation routines
<?php
// CREATE AN ARRAY OF RULES
// DEFAULT TYPE IS TO CHECK FOR EXISTENCE (min=1)
// THIS CAN BE EXPANDED TO CHECK FOR OTHER SPECIFIC
// FIELD TYPES
$required_fields = array(
  array('field' => 'firstname', 'min' => 3), 
  array('field' => 'lastname', 'min' => 1), 
  array('field' => 'usertype', 'min' => 1), 
  array('field' => 'email', 'type' => 'email'),
  array('field' => 'password', 'min' => 6)
);
// GENERIC VALIDATE FUNCTION.  TAKES AN ASSOC ARRAY OF 
// INPUT DATA AND AN ARRAY OF RULES AND PROCESSES THE RULES
// AGAINST THE INPUT DATA
// THE FUNCTION RETURNS AN OBJECT WITH SANTIZED DATA AND ERRORS
function validate_post_data($data, $fields)
{
  $return = new stdClass;
  $return->errors = [];
  $return->data = [];

  foreach($fields as $f) {
    $field = $f['field'];
    $type = isset($f['type']) ? $f['type'] : 'length';
    $value = isset($data[$field]) ? filter_var($data[$field], FILTER_SANITIZE_STRING) : '';
    
    switch ($type) {
      case 'email':
        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
          $return->errors[] = "{$value} is not a valid email address";
        }
      break;
      default:
        $min = isset($f['min']) ? $f['min'] : 0;
        $len = strlen($value);
        if ($len < $min) {
          $return->errors[] = "{$field} is too short, must be {$min} characters long";
        }
    }
    
    $return->data[$f['field']] = $value;
  }
  
  return $return;
}

function valid_email_domain($email, $allowedDomains)
{
  $parts = explode("@", $email);
  $domain = array_pop($parts);

  return in_array($domain, $allowedDomains);
}

$data = array(
  'firstname' => 'Fred',
  'lastname' => 'smith',
  'email' => 'bob@somewhere.com',
  'usertype' => 'one',
  'password' => 'password'
);
$allowedDomains = ['email.com', 'outlook.com', 'testmail.com'];
$result = validate_post_data($data, $required_fields);
if (empty($result->errors)) {
  if (!valid_email_domain($result->data['email'], $allowedDomains)) {
    $result->errors[] = "Email domain is not allowed";
  }
}
if (empty($return->errors)) {
  // PROCEED WITH PROCESSING HERE
}

Open in new window

Hey Lorna,

Glad it worked.

Not really sure about online cloud courses. There are a lot of places online that you can use to learn a programming language. Which one is most suitable is subjective as it will depend on several things - your current experience, your budget, your needs etc.

Given some of the conversations we've had, I would suggest you start right at the very beginning. Understanding the basic concepts (variables / conditional logic / loops / functions / etc) are absolutely essential, and while it may mean going over stuff you already know, it certainly won't hurt.
 
Have a look at this one - it's completely free and really does start with the basics - https://www.homeandlearn.co.uk/php/php.html

Get yourself a decent local development environment (devenv) setup (WAMP Server on Windows is easy), make sure your PHP installation has XDebug enabled (it does with WAMP), find yourself a decent editor (I prefer Sublime), and then run through the courses in your own time.

Pretty much every developer will also spend an inordinate amount of time using the technical manuals at PHP.net. This will tell you everything you need to know about all the PHP functions. Learning how to read them is a bit of a trick, but once you get it, you'll be flying.

 And of course, use EE when you need help.