Nội dung bài viết
Video học lập trình mỗi ngày
Go 24 - [User Login Interface] Implementation Registration
Tiếp theo trong bài này, chúng ta sẽ triển khai quy trình người dùng đăng ký như thế nào? Quy trình đăng ký thực ra nó không hề đơn giản như những trường hợp ta nhìn thấy, là chỉ cần kiểm tra user
đó có tài khoản email or mobile phone có tồn tại trong dữ liệu hay không? Mà còn có nhiều điều chúng ta cần thực hiện nó. Sau đây là quy trình nằm trong IUserLogin
thuộc interface trong dự án. Phần đầy đủ và thực tế nằm đây: FULL CODE: User Registration User
Quy trình đăng ký của một user trong Shopdev (7 bước)
Bước 1: Đầu tiên qua trình đăng ký thì user sẽ kèm theo body như sau:
VerifyKey string `json:"verify_key"`
VerifyType int `json:"verify_type"`
VerifyPurpose string `json:"verify_purpose"`
VerifyKey
chính là email
or number phone
mà hệ thống xác nhận cho phép đăng ký, VerifyType
đây là loại gì? 1 là EMAIL, 2 là PHONE sẽ được định nghĩa thông qua internal/consts/const_code.go
. Và tham số thứ 3 sẽ là VerifyPurpose
chính là loại hình mục đích, nếu là test
thì otp = 123456
nhằm giúp dev có thể test nhanh cùng với tester.
Tiếp theo trong video FULL CODE: User Registration User chúng ta có thể bước đầu tiền là phải mã hoá in.VerifyKey
vì sao? Vì nguyên tắc bất cứ ai bất kể chính người làm ra sản phẩm cũng không thể biết được OTP này là của user nào. Ví dụ: userA@gmail.com
sẽ hash ra thì trở thành 1231343476dfvsdfgsdf456
do đó sử dụng util/crypto
để thực hiện điều này.
hashKey := crypto.GetHash(strings.ToLower(in.VerifyKey))
Bước 2: Khi đã mã hoá thành hashKey
tiếp theo, hãy check hashKey
này đã đăng ký or đã có trong dữ liệu bảng user_base
hay chưa? Nếu có return lại cho người dùng là: User đã đăng ký, vui lòng thực hiện việc quên mật khấu
// 2. check user exists in user base
userFound, err := s.r.CheckUserBaseExists(ctx, in.VerifyKey)
if err != nil {
return response.ErrCodeUserHasExists, err
}
if userFound > 0 {
return response.ErrCodeUserHasExists, fmt.Errorf("user has already registered")
}
Bước 3: Nếu user đó chưa đăng ký thì tiến hành việc send OTP thông qua 2 dịch vụ (kafka, aws email) trong video FULL CODE: User Registration User chúng ta đã biết cách thực hiện hết tất các các dịch vụ bao gồm kafka
, aws smtp
chúng ta sẽ nói ở bước tiếp theo, còn đây là cách tạo ra OTP
// 3. hey userKey lưu rtrong redis, với TTL = 60s cho một token.
// hãy cố gắng sử dụng tốc độc redis để chống SPAM OTP thông qua nhiều IPs
userKey := utils.GetUserKey(hashKey) //fmt.Sprintf("u:%s:otp", hashKey)
otpFound, err := global.Rdb.Get(ctx, userKey).Result()
// util..
switch {
case err == redis.Nil:
fmt.Println("Key does not exist")
case err != nil:
fmt.Println("Get failed::", err)
return response.ErrInvalidOTP, err
case otpFound != "":
return response.ErrCodeOtpNotExists, fmt.Errorf("")
}
Bước 4 và 5: Hãy nhớ rằng khi generator OTP
hãy cố gắng set OTP đó hết hạn trong vòng 1 phút, tốt nhất hãy sử dụng hai dữ liệu đó là redis
và mysql
. Một bên sẽ check và chống spam, một bên sẽ bảo mật dữ liệu
// 4. Generate OTP
otpNew := random.GenerateSixDigitOtp()
if in.VerifyPurpose == "TEST_USER" {
otpNew = 123456
}
fmt.Printf("Otp is :::%d\n", otpNew)
// 5. save OTP in Redis with expiration time
err = global.Rdb.SetEx(ctx, userKey, strconv.Itoa(otpNew), time.Duration(consts.TIME_OTP_REGISTER)*time.Minute).Err()
if err != nil {
return response.ErrInvalidOTP, err
}
Bước 6: Sử dụng kafka
or email SMTP
được xây dựng từ amazon service
để làm điều đó dưới đây:
Code như sau:
// send email OTP by JAVA
// 6/ Sen OTP
switch in.VerifyType {
case consts.EMAIL:
err = sendto.SendTextEmailOtp([]string{in.VerifyKey}, consts.HOST_EMAIL, strconv.Itoa(otpNew))
if err != nil {
return response.ErrSendEmailOtp, err
}
// 7. save OTP to MYSQL
result, err := s.r.InsertOTPVerify(ctx, database.InsertOTPVerifyParams{
VerifyOtp: strconv.Itoa(otpNew),
VerifyType: sql.NullInt32{Int32: 1, Valid: true},
VerifyKey: in.VerifyKey,
VerifyKeyHash: hashKey,
})
if err != nil {
return response.ErrSendEmailOtp, err
}
// 8. getlasId
lastIdVerifyUser, err := result.LastInsertId()
if err != nil {
return response.ErrSendEmailOtp, err
}
log.Println("lastIdVerifyUser", lastIdVerifyUser)
return response.ErrCodeSuccess, nil
case consts.MOBILE:
return response.ErrCodeSuccess, nil
}
// send OTP via Kafak JAVA
body := make(map[string]interface{})
body["otp"] = otp
body["email"] = email
bodyRequest, _ := json.Marshal(body)
message := kafka.Message{
Key: []byte("otp-auth"),
Value: []byte(bodyRequest),
Time: time.Now(),
}
err = global.KafkaProducer.WriteMessages(context.Background(), message)
if err != nil {
fmt.Printf("err send to kafka::%v\n", err)
return response.ErrSendEmailOtp
}
Bước 7: hãy lưu ý code phía trên, chúng ta nhận ra rằng khi OTP đã được send thì hãy ghi dữ liệu lại ở một table user_verify
nhắm thao tác trích xuất xem user này đã sử dụng hay chưa...
// 7. save OTP to MYSQL
result, err := s.r.InsertOTPVerify(ctx, database.InsertOTPVerifyParams{
VerifyOtp: strconv.Itoa(otpNew),
VerifyType: sql.NullInt32{Int32: 1, Valid: true},
VerifyKey: in.VerifyKey,
VerifyKeyHash: hashKey,
})
Quy trình đăng ký
user nó không phức tạp đúng không?
Source Code FULL
Bạn có thể get các thông tin ở đây:
FULL CODE: User Registration User