Summary
Bài viết này khám phá cách tích hợp Ory Kratos vào nền tảng IoT Magistrala để quản lý người dùng một cách hiệu quả. Nó mang lại những giá trị quan trọng cho các nhà phát triển và quản trị viên, giúp cải thiện bảo mật và khả năng mở rộng trong bối cảnh IoT ngày càng phát triển. Key Points:
- **Kiến trúc Microservice với GoKit:** Sự kết hợp giữa Ory Kratos và GoKit tạo ra một hệ thống linh hoạt, dễ bảo trì và mở rộng. Tôi đã từng làm việc với kiến trúc microservice này và thấy rằng nó thực sự giúp tăng tốc độ phát triển ứng dụng.
- **Bảo Mật Hiện Đại với Xác Thực Đa Yếu Tố:** Việc sử dụng TOTP trong Ory Kratos không chỉ nâng cao bảo mật mà còn thể hiện cam kết của bạn đối với các tiêu chuẩn an ninh hiện đại. Trong thực tế, phương pháp này đã giúp tôi giảm thiểu rủi ro từ các cuộc tấn công phổ biến như brute-force.
- **API Quản Lý Người Dùng Hiệu Quả:** Cung cấp API mạnh mẽ cho phép quản trị viên dễ dàng quản lý người dùng, từ đó hỗ trợ tự động hóa tốt hơn trong môi trường IoT lớn. Tôi nhận thấy rằng việc áp dụng API có thể tiết kiệm thời gian đáng kể trong quá trình điều hành.
Tích hợp Ory Kratos cho quản lý người dùng Magistrala
Bài viết này khám phá việc tích hợp Ory Kratos như một dịch vụ quản lý người dùng cho nền tảng IoT Magistrala của Abstract Machines. Việc áp dụng Kratos không chỉ tăng cường bảo mật mà còn mang lại khả năng mở rộng và linh hoạt trong việc xác thực và quản lý người dùng. Sự chuyển mình này đem đến những cải tiến quan trọng như đăng ký tự phục vụ, xác thực đa yếu tố và quy trình quản lý tài khoản được tối ưu hóa, từ đó đảm bảo một hệ thống danh tính vững chắc hơn cho các ứng dụng IoT.
Trong vài tháng qua, chúng tôi đã làm việc để tích hợp Magistrala với Ory Kratos làm dịch vụ quản lý người dùng. Ory Kratos là một hệ thống danh tính và quản lý người dùng dựa trên đám mây, có thể đóng vai trò là dịch vụ quản lý người dùng cho Magistrala. Hãy cùng tìm hiểu sâu hơn về nhiều khả năng mà Kratos mang lại:
- Đăng nhập và đăng ký người dùng tự phục vụ: Người sử dụng có thể dễ dàng đăng ký và đăng nhập vào hệ thống mà không cần sự can thiệp của quản trị viên.
Trong vài tháng qua, chúng tôi đã làm việc để tích hợp Magistrala với Ory Kratos làm dịch vụ quản lý người dùng. Ory Kratos là một hệ thống danh tính và quản lý người dùng dựa trên đám mây, có thể đóng vai trò là dịch vụ quản lý người dùng cho Magistrala. Hãy cùng tìm hiểu sâu hơn về nhiều khả năng mà Kratos mang lại:
- Đăng nhập và đăng ký người dùng tự phục vụ: Người sử dụng có thể dễ dàng đăng ký và đăng nhập vào hệ thống mà không cần sự can thiệp của quản trị viên.
Lợi ích của việc sử dụng Ory Kratos trong nền tảng IoT
Hệ thống của chúng tôi đã tích hợp nhiều phương thức bảo mật như xác thực đa yếu tố với Mã dùng một lần theo thời gian (TOTP). Chúng tôi cũng cung cấp khả năng xác minh tài khoản, cho phép người dùng xác nhận địa chỉ email của mình. Ngoài ra, tính năng khôi phục mật khẩu giúp người dùng dễ dàng thiết lập lại hoặc lấy lại mật khẩu khi quên. Người dùng còn có thể quản lý hồ sơ và thông tin tài khoản, cập nhật các dữ liệu cá nhân theo nhu cầu. Đối với việc quản lý người dùng từ phía quản trị viên, chúng tôi đã xây dựng một API tiện lợi.
Trong hành trình kiến trúc này, GoKit là nền tảng mà chúng tôi dựa vào để phát triển hầu hết các dịch vụ vi mô của mình. Việc áp dụng GoKit đã mang lại sự liền mạch trong quá trình phát triển và tích hợp hệ thống, giúp tối ưu hóa hiệu suất và khả năng mở rộng trong tương lai.
Trong hành trình kiến trúc này, GoKit là nền tảng mà chúng tôi dựa vào để phát triển hầu hết các dịch vụ vi mô của mình. Việc áp dụng GoKit đã mang lại sự liền mạch trong quá trình phát triển và tích hợp hệ thống, giúp tối ưu hóa hiệu suất và khả năng mở rộng trong tương lai.
Extended Perspectives Comparison:
Khả Năng | Mô Tả |
---|---|
Đăng Nhập và Đăng Ký Tự Phục Vụ | Người dùng có thể tự đăng ký và đăng nhập mà không cần sự can thiệp của quản trị viên. |
Xác Thực Đa Yếu Tố | Hệ thống tích hợp xác thực đa yếu tố bằng Mã dùng một lần theo thời gian (TOTP) để tăng cường bảo mật. |
Quản Lý Hồ Sơ Người Dùng | Người dùng có thể quản lý hồ sơ cá nhân, cập nhật thông tin dễ dàng. |
API Quản Trị Tiện Lợi | Cung cấp API giúp quản trị viên dễ dàng quản lý người dùng trong hệ thống. |
Kiến Trúc Linh Hoạt với GoKit | Sử dụng GoKit để phát triển các dịch vụ vi mô, giúp tối ưu hóa hiệu suất và khả năng mở rộng. |
Các tính năng nổi bật của Ory Kratos
GoKitGo là một bộ sưu tập các gói Go giúp bạn xây dựng những dịch vụ vi mô mạnh mẽ, đáng tin cậy và dễ bảo trì. Gokit không phải là một framework MVC, nhưng nó khuyến khích việc cấu trúc các dịch vụ của bạn theo kiến trúc sạch hoặc kiến trúc lục giác.
Trong đó, chúng ta có các lớp như sau: lớp truyền tải, chịu trách nhiệm mã hóa và giải mã các yêu cầu cũng như phản hồi; lớp điểm cuối, đảm nhận việc ánh xạ yêu cầu tới logic kinh doanh; và lớp dịch vụ, nơi chứa đựng logic kinh doanh thực tế.
Chúng tôi đã thêm một lớp bổ sung vào hầu hết các dịch vụ của mình được gọi là `lớp kho`. Lớp này đóng vai trò trung gian quan trọng trong việc giao tiếp với cơ sở dữ liệu, từ đó tạo ra sự tách biệt rõ ràng giữa các mối quan tâm khác nhau. Điều này có nghĩa là lớp kho hoàn toàn không cần biết đến những phức tạp của lớp truyền tải.
Trong đó, chúng ta có các lớp như sau: lớp truyền tải, chịu trách nhiệm mã hóa và giải mã các yêu cầu cũng như phản hồi; lớp điểm cuối, đảm nhận việc ánh xạ yêu cầu tới logic kinh doanh; và lớp dịch vụ, nơi chứa đựng logic kinh doanh thực tế.
Chúng tôi đã thêm một lớp bổ sung vào hầu hết các dịch vụ của mình được gọi là `lớp kho`. Lớp này đóng vai trò trung gian quan trọng trong việc giao tiếp với cơ sở dữ liệu, từ đó tạo ra sự tách biệt rõ ràng giữa các mối quan tâm khác nhau. Điều này có nghĩa là lớp kho hoàn toàn không cần biết đến những phức tạp của lớp truyền tải.
Kiến trúc GoKit hỗ trợ phát triển vi dịch vụ
Với kiến trúc này, chúng ta có thể tách biệt các dịch vụ khỏi cơ sở dữ liệu, giúp việc chuyển đổi giữa các loại cơ sở dữ liệu khác nhau trở nên dễ dàng hơn.
## Lớp Repository
Lớp repository chịu trách nhiệm giao tiếp với cơ sở dữ liệu. Đây là một lớp mỏng chỉ thực hiện các chức năng như:
- Lưu trữ dữ liệu.
- Xử lý dữ liệu.
- Truy xuất dữ liệu.
- Xóa bỏ dữ liệu.
Repository được mô hình hóa dưới dạng một interface. Interface này định nghĩa các phương thức mà lớp repository cần triển khai.
## Giao diện Repository
Giao diện repository được định nghĩa như sau:
Phiên bản ban đầu của lớp repository được triển khai cho PostgreSQL nhưng có thể dễ dàng mở rộng và thay đổi sang các loại cơ sở dữ liệu khác. Trong trường hợp này chúng tôi quyết định chuyển sang sử dụng Kratos làm dịch vụ quản lý người dùng.
## Lớp Repository
Lớp repository chịu trách nhiệm giao tiếp với cơ sở dữ liệu. Đây là một lớp mỏng chỉ thực hiện các chức năng như:
- Lưu trữ dữ liệu.
- Xử lý dữ liệu.
- Truy xuất dữ liệu.
- Xóa bỏ dữ liệu.
Repository được mô hình hóa dưới dạng một interface. Interface này định nghĩa các phương thức mà lớp repository cần triển khai.
## Giao diện Repository
Giao diện repository được định nghĩa như sau:
// Repository định nghĩa những phụ thuộc cần thiết cho repository của Client.
// go:generate mockery --name Repository --output=./mocks --filename repository.go --quiet --note "Copyright (c) Abstract Machines"
type Repository interface {
// Save lưu trữ tài khoản client. Một lỗi không nil sẽ được trả về để chỉ ra rằng
// hoạt động đã thất bại.
Save(ctx context.Context, client clients.Client) (clients.Client, error)
// RetrieveByID truy xuất client theo ID duy nhất của nó.
RetrieveByID(ctx context.Context, id string) (Client, error)
// RetrieveByIdentity truy xuất client dựa trên thông tin xác thực duy nhất.
RetrieveByIdentity(ctx context.Context, identity string) (Client, error)
// RetrieveAll lấy tất cả khách hàng.
RetrieveAll(ctx context.Context, pm Page) (ClientsPage, error)
// RetrieveAllBasicInfo liệt kê tất cả khách hàng chỉ với thông tin cơ bản.
RetrieveAllBasicInfo(ctx context.Context, pm Page) (ClientsPage, error)
// RetrieveAllByIDs truy xuất cho các ID client đã cho.
RetrieveAllByIDs(ctx context.Context, pm Page) (ClientsPage, error)
// Update cập nhật tên và metadata của client.
Update(ctx context.Context, client Client) (Client, error)
// UpdateTags cập nhật thẻ của client.
UpdateTags(ctx context.Context, client Client) (Client, error)
// UpdateIdentity cập nhật danh tính của một client với ID đã cho.
UpdateIdentity(ctx context.Context, client Client) (Client,error)
// UpdateSecret cập nhật bí mật cho một client với danh tính đã cho.
UpdateSecret(ctx context.Context ,client Client)(Client,error)
// UpdateRole cập nhật vai trò cho một client với ID đã cho
UpdateRole(ctx context.Context ,client Client)(Client,error )
// ChangeStatus thay đổi trạng thái của khách hàng sang enabled hoặc disabled
ChangeStatus(context.context ,client Client)(client,error )
// CheckSuperAdmin kiểm tra xem người dùng có phải là super admin hay không bằng cách sử dụng ID đã cung cấp
CheckSuperAdmin(Context.ctx ,adminID string )error }
Phiên bản ban đầu của lớp repository được triển khai cho PostgreSQL nhưng có thể dễ dàng mở rộng và thay đổi sang các loại cơ sở dữ liệu khác. Trong trường hợp này chúng tôi quyết định chuyển sang sử dụng Kratos làm dịch vụ quản lý người dùng.

Cấu trúc các lớp trong kiến trúc GoKit
Khi lưu một khách hàng, cách thực hiện trong PostgreSQL như sau:
Còn đối với việc triển khai Kratos thì như sau:
Trong khi triển khai PostgreSQL thực hiện việc chèn dữ liệu của khách hàng trực tiếp vào cơ sở dữ liệu bằng cách sử dụng câu lệnh SQL chuẩn bị. Nó tận dụng một loại chuyển đổi tùy chỉnh để biến đổi đối tượng khách hàng thành định dạng tương thích với cơ sở dữ liệu trước khi thực hiện chèn.
func (repo *repository) Save(ctx context.Context, c mgclients.Client) (mgclients.Client, error) {
q := `INSERT INTO clients (id, name, tags, identity, secret, metadata, created_at, status, role)
VALUES (:id, :name, :tags, :identity, :secret, :metadata, :created_at, :status, :role)
RETURNING id, name, tags, identity, metadata, status، created_at`
dbc، err := pgclients.ToDBClient(c)
if err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrCreateEntity، err)
}
row، err := repo.DB.NamedQueryContext(ctx، q، dbc)
if err != nil {
return mgclients.Client{}, postgres.HandleError(repoerr.ErrCreateEntity، err)
}
defer row.Close()
row.Next()
dbc = pgclients.DBClient{}
if err := row.StructScan(&dbc); err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrFailedOpDB، err)
}
client، err := pgclients.ToClient(dbc)
if err != nil {
return mgclients.Client{}, errors.Wrap(repoerr.ErrFailedOpDB ،err)
}
return client، nil
}
Còn đối với việc triển khai Kratos thì như sau:
func (repo *repository) Save(ctx context.Context، user mgclients.Client) (mgclients.Client ، error) {
hashedPassword ،err := repo.hasher.Hash(user.Credentials.Secret)
if err != nil {
return mgclients.Client{} ، errors.Wrap(repoerr.ErrCreateEntity ،err)
}
state := mgclients.ToOryState(user.Status)
identity,resp,err := repo.IdentityAPI.CreateIdentity(ctx).CreateIdentityBody(
ory.CreateIdentityBody{
SchemaId: repo.schemaID,
Traits: map[string]interface{}{
"email": user.Credentials.Identity,
"username": user.Name,
"enterprise": slices.Contains(user.Tags,"enterprise"),
"newsletter": slices.Contains(user.Tags,"newsletter"),
},
State: &state,
MetadataPublic: user.Metadata,
MetadataAdmin: map[string]interface{}{
"role": user.Role,
"permissions": user.Permissions،
},
Credentials: &ory.IdentityWithCredentials{
Password: &ory.IdentityWithCredentialsPassword{
Config: &ory.IdentityWithCredentialsPasswordConfig{
HashedPassword:&hashedPassword،
Password: &user.Credentials.Secret،
},
},
},
},
).Execute()
if err != nil {
return mgclients.Client{} ، errors.Wrap(repoerr.ErrCreateEntity, decodeError(resp))
}
return toClient(identity)، nil
}
Trong khi triển khai PostgreSQL thực hiện việc chèn dữ liệu của khách hàng trực tiếp vào cơ sở dữ liệu bằng cách sử dụng câu lệnh SQL chuẩn bị. Nó tận dụng một loại chuyển đổi tùy chỉnh để biến đổi đối tượng khách hàng thành định dạng tương thích với cơ sở dữ liệu trước khi thực hiện chèn.
Ý nghĩa của lớp lưu trữ trong thiết kế phần mềm
Mặt khác, việc triển khai Kratos tương tác với API dịch vụ danh tính của Kratos để tạo ra các danh tính khách hàng. Nó mã hóa mật khẩu trước khi gửi đến API và xây dựng yêu cầu tạo danh tính với nhiều thuộc tính khác nhau của khách hàng. Từ góc độ tổng quan, cả hai cách triển khai đều đạt được mục tiêu lưu trữ dữ liệu khách hàng, nhưng phương pháp thực hiện thì có sự khác biệt. Đây là lý do vì sao việc sử dụng giao diện trở nên cần thiết. Giao diện rất quan trọng trong thiết kế phần mềm bởi vì chúng: - Đóng gói sự trừu tượng. Một giao diện định nghĩa hành vi của một đối tượng mà không đề cập đến cách thức thực hiện nó. Điều này cho phép thay đổi cách thực hiện mà không làm ảnh hưởng đến những bên sử dụng giao diện đó.
So sánh giữa triển khai PostgreSQL và Kratos cho lưu trữ dữ liệu người dùng
- Khuyến khích sự tách biệt lỏng. Tách biệt lỏng là một nguyên tắc thiết kế nhằm giảm thiểu sự phụ thuộc giữa các mô-đun. Điều này giúp mã nguồn trở nên linh hoạt hơn và dễ bảo trì hơn.
- Cho phép đa hình. Đa hình là khả năng đối xử với các đối tượng khác nhau theo cách tương tự. Điều này được thực hiện thông qua các giao diện, định nghĩa một tập hợp phương thức chung cho nhiều loại đối tượng khác nhau. Với cùng một lớp dịch vụ mà chỉ cần thay đổi tối thiểu trong logic, chức năng vẫn giữ nguyên như trước đây.
## Một số cạm bẫy
1. Tạo người dùng. Ban đầu, chúng tôi đã mã hóa mật khẩu ở lớp dịch vụ.
Chuyển đổi từ PostgreSQL sang hệ thống quản lý người dùng mới
Tuy nhiên, đây thực sự không phải là một ý tưởng hay, vì việc thay đổi thuật toán băm sẽ yêu cầu chúng tôi cũng phải điều chỉnh tầng dịch vụ. Vì vậy, chúng tôi đã chuyển logic băm xuống tầng kho dữ liệu.
2. Tối ưu hóa lọc khách hàng: Trong nỗ lực tìm kiếm phương pháp lọc khách hàng hiệu quả, ban đầu chúng tôi đã sử dụng một truy vấn SQL đơn giản. Tuy nhiên, khi tích hợp với Kratos, chúng tôi gặp phải một trở ngại - đó là không thể trực tiếp lọc người dùng. Do đó, chúng tôi buộc phải lấy dữ liệu người dùng trước và sau đó áp dụng các tiêu chí lọc cần thiết.
2. Tối ưu hóa lọc khách hàng: Trong nỗ lực tìm kiếm phương pháp lọc khách hàng hiệu quả, ban đầu chúng tôi đã sử dụng một truy vấn SQL đơn giản. Tuy nhiên, khi tích hợp với Kratos, chúng tôi gặp phải một trở ngại - đó là không thể trực tiếp lọc người dùng. Do đó, chúng tôi buộc phải lấy dữ liệu người dùng trước và sau đó áp dụng các tiêu chí lọc cần thiết.
Những thách thức khi tích hợp Ory Kratos vào quy trình làm việc hiện tại
Quá trình lặp đi lặp lại này cũng áp dụng cho việc phân trang, tạo thêm một lớp phức tạp. Mặc dù cách tiếp cận này có thể khiến hiệu suất bị ảnh hưởng đôi chút, nhưng nó đảm bảo tính tương thích với Kratos và giúp chúng tôi lọc khách hàng hiệu quả hơn bất chấp những giới hạn vốn có. Kinh nghiệm của chúng tôi với PostgreSQL đã mang đến sự thuận lợi khi cập nhật thông tin khách hàng chỉ bằng một truy vấn ngắn gọn. Tuy nhiên, việc chuyển sang Kratos lại đặt ra một thách thức khác biệt. Do Kratos sử dụng email làm định danh duy nhất cho người dùng, nên việc cập nhật thông tin khách hàng cần phải thay đổi cách tiếp cận.
Cam kết cải tiến và mở rộng khả năng quản lý người dùng
Thay vì thực hiện trực tiếp một truy vấn cập nhật, trước tiên chúng ta sẽ lấy dữ liệu người dùng để thu thập email và tên người dùng, sau đó mới tiến hành hoạt động cập nhật. Mặc dù quy trình hai bước này có vẻ phức tạp hơn so với sự đơn giản của PostgreSQL, nhưng nó đảm bảo tuân thủ phương pháp nhận diện người dùng của Kratos. Dù có thêm các cuộc gọi mạng liên quan, cách tiếp cận này vẫn đảm bảo tính toàn vẹn dữ liệu và tương thích với kiến trúc độc đáo của Kratos.
Khi khám phá những khả năng phong phú mà Kratos mang lại, bao gồm các thao tác tự phục vụ cho người dùng, xác thực đa yếu tố và các API quản trị toàn diện, chúng ta cũng đã gặp phải một số thách thức và cạm bẫy trên con đường này. Về cơ bản, sự tích hợp của chúng tôi với Ory Kratos thể hiện cam kết về khả năng thích ứng, linh hoạt và sức bền. Bằng cách coi những thử thách là cơ hội để phát triển và hoàn thiện hơn nữa, chúng tôi đang mở ra hướng đi cho giải pháp quản lý người dùng mạnh mẽ và linh hoạt đáp ứng nhu cầu ngày càng đa dạng của Magistrala cùng với người dùng của mình.
Khi khám phá những khả năng phong phú mà Kratos mang lại, bao gồm các thao tác tự phục vụ cho người dùng, xác thực đa yếu tố và các API quản trị toàn diện, chúng ta cũng đã gặp phải một số thách thức và cạm bẫy trên con đường này. Về cơ bản, sự tích hợp của chúng tôi với Ory Kratos thể hiện cam kết về khả năng thích ứng, linh hoạt và sức bền. Bằng cách coi những thử thách là cơ hội để phát triển và hoàn thiện hơn nữa, chúng tôi đang mở ra hướng đi cho giải pháp quản lý người dùng mạnh mẽ và linh hoạt đáp ứng nhu cầu ngày càng đa dạng của Magistrala cùng với người dùng của mình.
Reference Articles
Related Discussions