- Tạo ứng dụng Spring Boot bằng Spring Launchizr
- Cấu hình Cassandra trong Spring Boot
- Định cấu hình nhóm kết nối Tomcat trên Spring Boot
- Định tuyến tin nhắn Camel đến Artemis được nhúng bằng WildFly
Bài viết này được chia sẻ từ Cộng đồng Huawei Cloud"Thảo luận hai cách lưu trữ Token trong Redis", tác giả: Lạc Diệp Phiêu.
Bài viết này thảo luận về một vấn đề:
Khi lưu trữ mã thông báo, ai sẽ đóng vai trò là chìa khóa giữa mã thông báo và ID người dùng tương ứng?
Vấn đề bắt nguồn từ nhu cầu thêm tính năng quản lý quyền vào hệ thống quản lý phụ trợ của công ty. Khung mã nguồn mở đã được chọn, nhưng hệ thống ban đầu đã sử dụng mã thông báo để xác minh đăng nhập.
Phương pháp xác minh Shiro mà tôi sử dụng là lấy ID người dùng dựa trên mã thông báo cho từng yêu cầu giao diện, sau đó thực hiện xác minh quyền thông qua cơ chế xác minh đăng nhập trong Shira.
Do đó, việc "lấy ID người dùng dựa trên mã thông báo" yêu cầu khi lưu trữ mã thông báo người dùng, mã thông báo được sử dụng làm khóa và ID người dùng được sử dụng làm giá trị.
Tuy nhiên, một vấn đề gặp phải vào thời điểm này là phương thức lưu trữ mã thông báo ban đầu của hệ thống như sau, mà chúng tôi gọi là loại đầu tiên: ID người dùng là khóa.
cache.set(TOKEN_PREFIX + userid, token);
Điều này đòi hỏi tôi phải đưa ra phán đoán xem liệu tôi có cần sửa đổi phương thức lưu trữ mã thông báo thành dạng sau hay không: Chúng tôi gọi đó là loại thứ hai: mã thông báo là khóa.
cache.set(TOKEN_PREFIX + token, userid);
Các chức năng chúng ta cần thực hiện bao gồm:
Xác minh đăng nhập
Đối với phương thức "user ID as key", giao diện người dùng cần chuyển hai giá trị id người dùng + mã thông báo. Để xác minh trạng thái đăng nhập, chúng ta cần lấy mã thông báo được lưu trữ trong cơ sở dữ liệu dựa trên ID người dùng. được giao diện người dùng chuyển qua và xác minh nó bằng mã thông báo do giao diện người dùng chuyển. Nếu chúng nhất quán thì quá trình xác minh sẽ được chuyển, nếu không, thông báo lỗi sẽ được trả về, nhắc người dùng đăng nhập lại, v.v.
Đối với phương thức "mã thông báo làm khóa", giao diện người dùng cần chuyển ít nhất một giá trị của mã thông báo. Theo mã thông báo được giao diện người dùng chuyển, ID người dùng được lưu trữ trong cơ sở dữ liệu sẽ được lấy. Nếu không, người dùng sẽ được nhắc rằng mã thông báo đã hết hạn và người dùng được yêu cầu đăng nhập lại, v.v.
Xác minh quyền trong shiro
Việc xác minh quyền trong shiro bao gồm một cơ chế triển khai cụ thể, sử dụng mã thông báo làm chìa khóa. Hãy lấy việc triển khai thực tế của chúng tôi làm ví dụ:
// mã đăng nhập shiro: Chủ đề s = SecurityUtils.getSubject(); JWTToken jwtToken = new JWTToken(token); topic.login(jwtToken); // Lớp triển khai AuthenticationToken: import org.apache.shiro.authc.AuthenticationToken; lớp JWTToken triển khai AuthenticationToken { riêng tư cuối cùng dài serialVersionUID = 1L; Mã thông báo chuỗi riêng tư chính; public JWTToken(String token) { this.token = token; } @Override public Object getPrincipal() { return token; } @Override public Object getCredentials() { return token; lớp xác minh đăng nhập: */ lớp công khai ShiraDbRealm mở rộng AuthorizingRealm{ /** * Ghi đè mã thông báo của shiro */ @Ghi đè boolean công khai hỗ trợ (Mã thông báo xác thực) { return token instanceof JWTToken; } /** * Vai trò, xác thực quyền hạn*/ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection các nguyên tắc) { SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); tới tài khoản người dùng Truy vấn quyền vai trò của người dùng và thông tin khác trả về simpleAuthorizationInfo; } /** * Xác thực tùy chỉnh */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) ném AuthenticationException { String token = (String) auth.getCredentials(); // Giải mã để lấy userid để so sánh với cơ sở dữ liệu // getUserId thực tế là thông qua mã thông báo, trong Lấy userid tương ứng từ cơ sở dữ liệu Integer userid = JwtUtils.getUserId(token); (tuserid == null) { ném AuthenticationException mới ("xác minh mã thông báo không thành công"); } trả về SimpleAuthenticationInfo mới (mã thông báo, mã thông báo, getName());
Nếu userid được sử dụng làm khóa thì việc triển khai không khó và phương pháp triển khai cũng có thể được sửa đổi.
Phương thức đầu tiên yêu cầu giao diện người dùng chuyển mã thông báo+userid trong mọi yêu cầu; trong khi phương thức thứ hai thực sự chỉ có thể chuyển mã thông báo và nền lấy thông tin người dùng dựa trên giải mã mã thông báo (hoặc tìm kiếm cơ sở dữ liệu).
Tính bảo mật của hai phương thức phải giống nhau. Cốt lõi là lưu thông tin tương ứng giữa mã thông báo và userid thông qua cơ sở dữ liệu ở chế độ nền.
Cá nhân tôi muốn tinh chỉnh phương pháp thứ hai, sử dụng mã thông báo làm khóa. Thứ nhất, việc truyền tải giao diện người dùng rất đơn giản và chỉ cần chuyển mã thông báo thứ hai, thông qua phương pháp này, mặt sau có thể thống nhất phương thức mua lại; của người đăng nhập hiện tại thay vì mỗi lần đăng nhập.
Nhấp để theo dõi và tìm hiểu về các công nghệ mới của Huawei Cloud càng sớm càng tốt~
Tôi đã đọc về các hàm lắp ráp nhưng tôi bối rối không biết nên sử dụng lệnh nhập và thoát hay chỉ lệnh gọi/trả lại để thực thi nhanh. Một cách nhanh hơn và cách kia nhỏ hơn? Ví dụ: cách nhanh nhất để thực hiện việc này trong hợp ngữ mà không nội tuyến hàm (stdcal
Tôi đang làm việc với một danh sách các bộ dữ liệu như thế này: res = [('stori', 'JJ'), ('man', 'NN'), ('unnatur', 'JJ'), ('feel', 'NN'), ('lợn',
Gần đây tôi đã thực hiện rất nhiều liên kết mạng hoặc IO và việc sử dụng các luồng giúp tăng tốc mã. Tôi nhận thấy rằng tôi cứ viết đi viết lại mã như thế này: thread = [] cho máy, người dùng, dữ liệu
Giả sử tôi có một tài nguyên tên là user_stats chứa số lượng bài đăng, nhận xét, lượt thích và người theo dõi mà một người dùng có. Nếu có một cách RESTful để chỉ yêu cầu một phần của thống kê đó (ví dụ: đối với user_stats/3, vui lòng cho tôi biết
Tôi có một api đơn giản hoạt động như thế này: người dùng tạo một yêu cầu ( POST /requests ) một người dùng khác truy xuất tất cả các yêu cầu ( GET /requests ) rồi thêm dấu ngoặc kép vào yêu cầu ( POST /
Hãy xem xét ví dụ CDK sau bằng Python (không cần có kiến thức AWS cho câu hỏi này, về cơ bản nó sẽ hoạt động với mọi mẫu trình tạo, tôi chỉ sử dụng CDK trong ví dụ này vì tôi gặp phải vấn đề này khi sử dụng thư viện này.): từ aws
Cách ưa thích để quản lý nhóm đối tượng trong Scala là gì? Tôi cần tạo và xóa các đối tượng có quy mô lớn trong một luồng duy nhất (không cần đồng bộ hóa). Trong C++, tôi đã sử dụng một mảng đối tượng tĩnh. Cách thành ngữ và hiệu quả để xử lý nó trong Scala là gì? Câu trả lời hay nhất tôi sẽ đặt nó
Tôi có một lớp với một số phương thức tích hợp sẵn. Đây là một ví dụ trừu tượng về lớp: class Foo: def __init__(self): self.a = 0 self.b = 0
Cách trả về và kiểm tra việc thực thi phương thức Pythonic Tôi hiện đang sử dụng kiểu mã hóa golang trong mã python và quyết định chuyển sang cách Pythonic Ví dụ: nhập sys từ gõ imp
Tôi đang phát triển API RESTful. Một trong các URL cho phép người gọi yêu cầu hồ sơ về một người cụ thể theo id. Giá trị bình thường để trả về bản ghi không tồn tại cho id đó là gì? Máy chủ có nên gửi lại một đối tượng trống hoặc 404 hay thứ gì khác không?
Tôi đang sử dụng pathlib.Path() để kiểm tra xem tệp có tồn tại hay không và sử dụng rasterio để mở tệp dưới dạng hình ảnh.
Tôi đang tìm cách Pythonic để tạo từ điển lồng nhau từ danh sách và từ điển. Hai câu lệnh sau đây cho cùng một kết quả: a = [3, 4] b = {'a': 1, 'b': 2} c = dict(zip(b, a))
Tôi có một tập lệnh đang thao tác với thiết bị cắt. Các thiết bị đôi khi bị lỗi về mặt vật lý và khi xảy ra sự cố, tôi muốn đặt lại thiết bị và tiếp tục thực thi tập lệnh. Tôi có cái này: while True: thiết bị do_device_control()
Cách Pythonic và chính xác nhất để làm bí danh kết hợp là gì? Đây là một kịch bản giả định: class House: def cleanup(self, arg1, arg2, kwarg1=False):
Tôi đang phát triển một chương trình máy chủ khách hàng nhỏ để thu thập đơn đặt hàng. Tôi muốn thực hiện việc này theo cách "REST(ful)". Điều tôi muốn làm là: thu thập tất cả các dòng đơn hàng (sản phẩm và số lượng) và gửi đơn hàng hoàn chỉnh đến máy chủ. Hiện tại tôi thấy có hai tùy chọn: gửi từng dòng đơn hàng.
Tôi biết rằng trong Groovy bạn có thể sử dụng chuỗi để gọi các phương thức trên một lớp/đối tượng. Ví dụ: Foo."get"(1) /* hoặc */ String meth = "get" Foo."$meth"(1) Có cách nào không
Trong ECMAScript6, bạn có thể sử dụng toán tử trải rộng để hủy cấu trúc một đối tượng như const {a, ...rest} = obj; sao chép nông obj sang phần còn lại mà không có thuộc tính a. Có cách nào rõ ràng để làm điều này trong
Tôi có một số hàm trả về số hoặc Không có. Tôi muốn hàm bao bọc của mình trả về kết quả đầu tiên không phải là Không. Ngoài cách dưới đây ra còn cách nào khác không? def func1(): return Không có def func2(
Giả sử tôi muốn thiết kế một REST api để thảo luận về các bài hát, album và nghệ sĩ (thực ra đó là những gì tôi làm, giống như 1312414 người trước tôi). Nội dung bài hát luôn gắn liền với album mà chúng thuộc về. Thay vào đó, tài nguyên album được liên kết với tất cả các bài hát chứa trong đó.
Đây là một vấn đề mà tôi nghĩ phải xuất hiện thường xuyên nhưng tôi vẫn chưa tìm được giải pháp tốt. Giả sử tôi có một hàm chuyển một tài nguyên mở (như một tệp hoặc đối tượng kết nối cơ sở dữ liệu) làm tham số hoặc cần tự tạo một tài nguyên. Nếu hàm cần tự mở tệp, cách tốt nhất thường là
Tôi là một lập trình viên xuất sắc, rất giỏi!