Xác thực Email trong Java với regular expressions

Trong bài viết này chúng ta sẽ cùng nhau tìm cách kiểm tra tính hợp lệ của email sử dụng Java regular expressions.

Xác thực email trong Java

Xác thực email là điều bắt buộc đối với các ứng dụng cho phép người dùng đăng ký tài khoản qua email. 

Một địa chỉ email được chia thành ba phần chính: local part, ký hiệu @ và domain. Giả sử nếu “[email protected]” là một email thì:

  • local-part = username
  • @ = @
  • domain = domain.com

Nếu sử dụng các kỹ thuật thao tác chuỗi thông thường thì việc xác thực email sẽ rất khó khăn vì chúng ta thường cần đếm số lượng ký tự trong chuỗi, kiểm tra đầy đủ 3 thành phần chính của email v.v Thật may mắn là trong Java chúng ta có thể sử dụng regular expression giúp việc xác thực email trở nên đơn giản hơn.

Xác thực email với Regular Expression

Biểu thức regular expression đơn giản nhất mà chúng ta có thể sử dụng để xác thực địa chỉ email là: ^ (. +) @ (\ S +) $.

Nó chỉ kiểm tra sự hiện diện của ký hiệu @ trong địa chỉ email. Nếu có, thì kết quả xác nhận trả về true, ngược lại, kết quả là false. Biểu thức này sẽ không xác thực phần local part và domain của email.

Ví dụ: theo biểu thức chính quy này, [email protected] sẽ vượt qua bài kiểm tra của vì username và domain.com không cần xác thực.

public class Main {

    public static void main(String[] args) throws Exception {
        String emailAddress = "[email protected]";
        String regexPattern = "^(.+)@(\\S+)$";
        System.out.println("Result: " + patternMatches(emailAddress, regexPattern));

    }
    public static boolean patternMatches(String emailAddress, String regexPattern) {
        return Pattern.compile(regexPattern)
                .matcher(emailAddress)
                .matches();
    }
}

Output: Result: true

Xác thực email nâng cao với Regular Expression

Ở phần này chúng ta sẽ triển khai một biểu thức chính quy phức tạp hơn nhằm tăng mức độ kiểm tra lên cả 3 phần local part, ký hiệu @ và cả domain: ^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$

Chuỗi regex sẽ kiểm tra theo các điều khoản sau:

  • Cho phép các ký tự số từ 0 đến 9
  • Cho phép cả chữ hoa và chữ thường từ a đến z
  • Cho phép các ký tự đặc biệt gạch dưới “_”, gạch nối “-” và dấu chấm “.”
  • Dấu chấm không được phép ở đầu và cuối phần local part
  • Các dấu chấm liền nhau sẽ vi phạm
  • Đối với phần local part, số lượng ký tự đối ta là 64
public class Main {

    public static void main(String[] args) throws Exception {
        String emailAddress = "[email protected]";
        String regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"
                + "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
        System.out.println("Result: " + patternMatches(emailAddress, regexPattern));

    }
    public static boolean patternMatches(String emailAddress, String regexPattern) {
        return Pattern.compile(regexPattern)
                .matcher(emailAddress)
                .matches();
    }
}

Output: Result: true

Dưới đây là một danh sách các địa chỉ email hợp lệ khi sử dụng chuỗi regex này: 

Và một số địa chỉ email không hợp lệ như:

Xác thực email theo chuẩn RFC 5322

Thay vì phải tốn công sức để viết ra một chuỗi regex để xác thực email, chúng ta có thể sử dụng một regex được cung cấp bởi tiêu chuẩn RFC: ^[a-zA-Z0-9_!#$%&’*+/=?`{|}~^.-][email protected][a-zA-Z0-9.-]+$

Như chúng ta có thể thấy, đó là một regex rất đơn giản cho phép tất cả các ký tự trong email.

Tuy nhiên, nó không cho phép ký tự  (|) và dấu nháy đơn (‘) vì những ký tự này tiềm ẩn nguy cơ thực hiện các cuộc tấn công bằng SQL injection.

public class Main {

    public static void main(String[] args) throws Exception {
        String emailAddress = "[email protected]";
        String regexPattern = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-][email protected][a-zA-Z0-9.-]+$";
        System.out.println("Result: " + patternMatches(emailAddress, regexPattern));

    }
    public static boolean patternMatches(String emailAddress, String regexPattern) {
        return Pattern.compile(regexPattern)
                .matcher(emailAddress)
                .matches();
    }
}

Output: Result: true

Xác thực email với theo tiêu chuẩn OWASP

Biểu thức  regular expression này được cung cấp bởi tổ chức OWASP để kiểm tra xác thực email: ^[a-zA-Z0-9_+&*-] + (?:\\.[a-zA-Z0-9_+&*-] + )*@(?:[a-zA-Z0-9-]+\\.) + [a-zA-Z]{2, 7}

public class Main {

    public static void main(String[] args) throws Exception {
        String emailAddress = "[email protected]";
        String regexPattern = "[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
        System.out.println("Result: " + patternMatches(emailAddress, regexPattern));

    }
    public static boolean patternMatches(String emailAddress, String regexPattern) {
        return Pattern.compile(regexPattern)
                .matcher(emailAddress)
                .matches();
    }
}

Xác thực Email với Apache Commons Validator

Apache Commons Validator là một thư viện mã nguồn mã cung cấp các tiêu chuẩn xác thực. Để sử dụng thư viện này trong maven chúng ta cần thêm dependency sau:

dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>${validator.version}</version>
</dependency>

Chúng ta có thể sử dụng class EmailValidator để xác thực email dựa trên tiêu chuẩn. RFC 822

public class Main {

    public static void main(String[] args) throws Exception {
        String emailAddress = "[email protected]";
        System.out.println("Result: " + EmailValidator.getInstance().isValid(emailAddress));

    }
}

Tóm lược

Qua bài viết này chúng ta đã tìm hiểu được một số cách cơ bản dùng để xác thực Email trong Java. Nếu không muốn dành quá nhiều thời gian cho việc này các bạn có thể sử dụng Apache Commons Validator để xác thực. Việc sử dụng này có một lợi thế là việc xác thực email luôn được đội ngũ phát triển cập nhật theo thời gian, việc của chúng ta chỉ là cập nhập thư viện lên các phiên bản mới.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x