Create Register & Login using ASP Core 2.1 + React (part 1)

Cũng khá lâu rồi! không chia sẻ với mọi người, này mình sẽ làm một ví dụ tương đối hay và thường hay dùng trong các dự án đó là:Login & Register trong React + ASP Core. Để làm được ví dụ này bạn cần phải xem lại giúp mình bài hướng dẫn về cách tạo project ASP Core + React
+ Building a Simple React with ASP Core 2.1

Sau khi bạn đã xem bài viết trên và đã tạo được project ASP Core 2.1 + React. Tiếp theo mình sẽ chia bài này thành 2 phần
+ Phần 1: Xây dựng Back-End trong ASP Core 2.1
+ Phần 2: Xây dựng Front-End trong React

Xây dựng Back-End trong ASP Core 2.1

Đầu tiên bạn mở project bằng Visual Studio 2019,Tiếp theo vào phần Manager Nuget Packages để cái cho mình một số thư viện hổ trợ sau:

Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer : Hổ trợ xử lý connect SQL SERVER
Microsoft.EntityFrameworkCore.Tools : Hổ trợ xử lý các câu lệnh migration 

Bạn nào chưa biết về ASP Core 2.1 bạn có thể xem lại tại đây: Create Database using Code First in ASP.NET CORE 2.1
Tiếp tục ta cần cấu hình chuỗi kết nối SQL SERVER của ta, các bạn nhớ cái SQL SERVER vào máy tính để dùng nhé

Mở appsettings.json trong project

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "EFDataContext": "Server=DESKTOP-2F1MPHI\\SQLEXPRESS;Database=DemoReact;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

Nếu bạn đã xem qua một loạt hướng dẫn về ASP Core của mình thì các bạn sẽ hiểu rõ hơn, chuỗi kết nối trên bạn phải chú ý Phần
+ Server name SQL SERVER máy tính của bạn
+ Database: trong đoạn chuỗi trên mình đặt là "DemoReact", các bạn đặt sao cũng được (chú ý: không cần tạo Cơ sở dữ liệu sẵn trong SQL SERVER, bởi vì hồi mình sẽ chạy câu lệnh migration, project sẽ tự tạo Database và tự động liên kết với SQL SERVER)

Okay, giờ chúng tạo vào thư mục Models trong project: tạo cho file User.cs chứa các thuộc tính của mô hình table Users
+ Models/User.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Http;
using System.IO;

namespace LoginAspCoreReact.Models
{
    public class User
    {
        public int idUser { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public int Age { get; set; }
        public DateTime BirthDay { get; set; }
        public string Avatar { get; set; }
        public string Address { get; set; }

    }

    public class FormUserView{
        public string Name { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public int Age { get; set; }
        public DateTime BirthDay { get; set; }
        public IFormFile Avatar { get; set; }
        public string Address { get; set; }
    }

}

+ Models/EFDataContext.cs :  cần phải tạo một class kế thừa từ DBContext để xử lý chuổi kết nối tới SQL SERVER của ta

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace LoginAspCoreReact.Models
{
    public class EFDataContext : DbContext
    {
        public EFDataContext(DbContextOptions<EFDataContext> options)
              : base(options){}
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //config primary key(User)
            modelBuilder.Entity<User>().HasKey(s => s.idUser);
        }
        public DbSet<User> Users { get; set; }
     

    }
}

Tiếp theo bạn hay mở file Startup.cs trong project lên và thêm câu lệnh sau vào

services.AddDbContext<EFDataContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("EFDataContext")));

+ Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using LoginAspCoreReact.Models;
using Microsoft.EntityFrameworkCore;
namespace LoginAspCoreReact
{
    public class Startup
    {
        readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy(name: MyAllowSpecificOrigins,
                                  builder =>
                                  {
                                      builder.WithOrigins("http://localhost:3000",
                                                          "https://localhost:44382");
                                  });
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // In production, the React files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/build";
            });
            services.AddDbContext<EFDataContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("EFDataContext")));
            
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();
            app.UseCors(MyAllowSpecificOrigins);
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });
            
            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
           
        }
    }
}

Trong đoạn code trên, mình có cấu hình Cors để khi ta gửi yêu cầu từ React đến ASP Core 2.1 nó không bị báo lỗi Cors
Okay vậy là xong, giờ ta cần thự hiện lệnh Migration để tạo Database, mở cmd lên và chạy câu lệnh sau
# add-migration demoreact
# update-database

Sau khi tạo xong nếu không có lỗi gì xãy ra bạn sẽ được một folder Migrations trong project, và đồng thời có database được tạo trong SQL SERVER của bạn
Giờ ta đã có Database giờ ta chỉ cần cấu hình controller với các phương thức nhận xử lý hành động khi React gửi yêu cầu qua thôi
+ Controllers/UsersController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using LoginAspCoreReact.Models;
using System.IO;
using System.Security.Cryptography;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace LoginAspCoreReact.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UsersController : ControllerBase
    {
        public EFDataContext _db;
        public UsersController(EFDataContext db)
        {
            this._db=db;
        }
        [HttpPost]
        [Route("login")]
        public ActionResult PostLogin(FormUserLogin _user)
        {
             try
              {
                  var check = _db.Users.Where(s => s.Email == _user.Email && s.Password == GetMD5(_user.Password)).FirstOrDefault();
                  if (check.idUser>0)
                  {
                      return Ok(check);
                  }
                  return Ok(0);

              }
             catch(Exception e)
              {
                return Ok(e);
              }
           
        }
        [HttpPost]
        [Route("register")]
        public async Task<ActionResult> Post([FromForm] FormUserView _user)
        {
            var check = _db.Users.Where(s => s.Email == _user.Email.ToLower()).ToList();
            if (check.Count() > 0)
            {
                return Ok(-1);
            }
            var user = new User
            {
                Name = _user.Name,
                Age = _user.Age,
                Email = _user.Email.ToLower(),
                Address = _user.Address,
                Password = GetMD5(_user.Password),
                BirthDay = _user.BirthDay

            };
            var filesPath = Directory.GetCurrentDirectory() + "/images";
            //get filename
            string ImageName = Path.GetFileName(_user.Avatar.FileName);
            var fullFilePath = Path.Combine(filesPath, ImageName);
            using (var stream = new FileStream(fullFilePath, FileMode.Create))
            {
                await _user.Avatar.CopyToAsync(stream);
            }
            user.Avatar = filesPath + "/" + ImageName;
           
            _db.Users.Add(user);
            await _db.SaveChangesAsync();
            int _insertID = user.idUser;
            if (_insertID > 0)
            {
                return Ok(_insertID);
            }
            return Ok(0); 
        }
        //create a string MD5
        public static string GetMD5(string str)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] fromData = Encoding.UTF8.GetBytes(str);
            byte[] targetData = md5.ComputeHash(fromData);
            string byte2String = null;

            for (int i = 0; i < targetData.Length; i++)
            {
                byte2String += targetData[i].ToString("x2");

            }
            return byte2String;
        }
    }
}

Mình sẽ bỏ qua giải thích cho từng method trong đoạn code file UsersController.cs trên, vì mình đã có nói sơ qua ở loạt bài viết về ASP MVC 5 & ASP Core 2.1. Mọi người có thể xem lại nhé
Vậy là xong phần Back-end

Bài Viết Liên Quan

Messsage

Ủng hộ tôi bằng cách click vào quảng cáo. Để tôi có kinh phí tiếp tục phát triển Website!(Support me by clicking on the ad. Let me have the money to continue developing the Website!)