Tài liệu này là một phần của hướng dẫn Hiểu về OAuth2 và Xây dựng Máy chủ Ủy quyền Cơ bản của riêng bạn. Nó thảo luận chi tiết về cách hoạt động của luồng Mã ủy quyền
Trước khi bắt đầuMã mẫu trong tài liệu này sử dụng Python 3 và khung bình. Nó chỉ dành cho mục đích trình diễn. Mã này được thiết kế để thể hiện quy trình ủy quyền theo cách dễ hiểu;
Thiết lập môi trường của bạn
- Cài đặt phiên bản Python 3 mới nhất. Xem Thiết lập Môi trường Phát triển Python để biết hướng dẫn
- Cài đặt các gói Python sau.
python AC_client.pypython AC_auth_server.pypython API_server.py
6,python AC_client.pypython AC_auth_server.pypython API_server.py
7,python AC_client.pypython AC_auth_server.pypython API_server.py
8 vàpython AC_client.pypython AC_auth_server.pypython API_server.py
9.//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
0 - Tạo một cặp khóa riêng tư/công khai [
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
1 và//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
2]
- Cài đặt phiên bản mới nhất của openssl
- Chuẩn bị khóa riêng.
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
0. Không chỉ định cụm mật khẩu - Chuẩn bị khóa công khai.
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
1
Đang tải xuống mã
Tải mã nguồn tại đây
Mẫu bao gồm các tệp sau
Chạy mã
Chạy mã riêng như sau
python AC_client.pypython AC_auth_server.pypython API_server.py
Ghé thăm khách hàng tại http. //127. 0. 0. 1. 5000. Máy chủ ủy quyền lắng nghe ở 127. 0. 0. 1. 5001 và máy chủ API khả dụng tại 127. 0. 0. 1. 5002
Cách hoạt động của luồng Mã ủy quyềnChuyển hướng người dùng đến trang đăng nhập do máy chủ ủy quyền cung cấp
Các luồng bắt đầu với việc người dùng truy cập đường dẫn
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
2. Đoạn mã sau trong //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
3 trình bày một trang đơn giản tại //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
2 hiển thị một nút nhắc người dùng đăng nhập bằng máy chủ ủy quyềnCác tham số
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
5, //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
6, //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
7 và //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
8 được chuyển để tạo URL chuyển hướng đầy đủ. Khi trang đã sẵn sàng, nhấn các nút sẽ chuyển hướng người dùng đến//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
Giá trị của
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
6, //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
20, cho biết việc khởi tạo luồng mã ủy quyền. Vì máy chủ ủy quyền trong mẫu này chỉ hỗ trợ một luồng nên giá trị không được sử dụng; . Ngoài ra, //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
7 xác định duy nhất ứng dụng khách và //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
8 là nơi gửi mã ủy quyềnPhương thức
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
23 của máy chủ ủy quyền chấp nhận các tham số này và hiển thị trang mô tả những gì khách hàng đang yêu cầu quyền truy cập vàoNguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/auth_server/AC_auth_server. py#L14Nếu người dùng đồng ý với các yêu cầu, họ có thể đăng nhập bằng thông tin đăng nhập của mình. Thông tin nhạy cảm, chẳng hạn như thông tin đăng nhập của người dùng, chỉ được xử lý bởi máy chủ ủy quyền, do đó bảo vệ người dùng [chủ sở hữu tài nguyên]. Lưu ý rằng trong bước này, máy chủ ủy quyền cũng xác minh xem yêu cầu từ máy khách [URL chuyển hướng] có khớp với yêu cầu của nó trong quá trình đăng ký hay không
Trả lại mã ủy quyền
Máy chủ ủy quyền xử lý thông tin xác thực mà người dùng cung cấp bằng phương thức
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
24; Nguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/auth_server/AC_auth_server. py#L43Mã ủy quyền được tạo bằng phương pháp
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
25Nguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/auth_server/auth. py#L43Đối với mã ủy quyền, mẫu này mã hóa chuỗi JSON chứa các trường
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
7 và //localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
8 bằng Fernet, một phương pháp mã hóa đối xứng. Bạn cũng có thể tạo mã ủy quyền ở các định dạng khác, miễn là nó phù hợp với các tiêu chí sau- Hết hạn sau một khoảng thời gian [ví dụ 10 phút]
- Giới hạn tới
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
7 và//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
8
Ngoài ra, một mã ủy quyền chỉ có thể được sử dụng một lần, điều đó có nghĩa là bạn cần lưu giữ hồ sơ về các mã ủy quyền đã cấp. Đoạn mã trên lưu trữ chúng, cùng với ngày hết hạn tương ứng của chúng, trong bộ nhớ cùng với từ điển, để giữ cho mẫu càng đơn giản càng tốt;
Sau khi mã ủy quyền được tạo, người dùng được chuyển hướng trở lại máy khách với mã được nhúng trong yêu cầu
Trao đổi mã ủy quyền lấy mã thông báo truy cập
Khách hàng nhận được mã ủy quyền tại đường dẫn
python AC_client.pypython AC_auth_server.pypython API_server.py60. Sau đó, mã được gửi trở lại máy chủ ủy quyền, cùng với
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
7, python AC_client.pypython AC_auth_server.pypython API_server.py62 và
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
8, để đổi lấy mã thông báo truy cậpNguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/client/AC_client. py#L55Vì lý do đơn giản, ở cuối phương thức, mã thông báo truy cập được ghi vào cookie khi nó được máy chủ ủy quyền trả về. Tuy nhiên, trong thế giới thực, hầu hết các nhà phát triển thích lưu trữ mã thông báo truy cập trong Bộ lưu trữ web HTML [đối với ứng dụng web] hoặc bộ nhớ cục bộ [đối với ứng dụng di động] thay vì. Cần chỉ ra rằng việc lưu mã thông báo truy cập vào cookie không tạo ra OAuth 2. 0 chuyển một biến thể của ủy quyền dựa trên cookie. mã thông báo, mặc dù nằm trong cookie, nhưng không bao giờ được chuyển qua cookie;
Xác thực thông tin đăng nhập và trả lại mã thông báo truy cập
Phương thức
python AC_client.pypython AC_auth_server.pypython API_server.py64 của máy chủ ủy quyền [
python AC_client.pypython AC_auth_server.pypython API_server.py65] lắng nghe mã ủy quyền đến, xác thực chúng và trả lời bằng mã thông báo truy cậpNguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/auth_server/AC_auth_server. py#L72
Phương thức
python AC_client.pypython AC_auth_server.pypython API_server.py66, như tên gọi của nó, kiểm tra xem
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
7 và python AC_client.pypython AC_auth_server.pypython API_server.py62 có khớp không. Mặt khác, phương thức
python AC_client.pypython AC_auth_server.pypython API_server.py69 xác nhận rằng mã ủy quyền hợp lệ. Phương pháp trước đây là giả trong mẫu; . Bạn nên thay thế chúng bằng logic xác minh của riêng bạn. Tuy nhiên, phương pháp thứ hai được định nghĩa trong
python AC_client.pypython AC_auth_server.pypython API_server.py71Nguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/auth_server/auth. py#L62
Ngoài ra, phương pháp
python AC_client.pypython AC_auth_server.pypython API_server.py72 được định nghĩa như sau
Mẫu này sử dụng gói pyjwt để tạo JWT.
python AC_client.pypython AC_auth_server.pypython API_server.py73 là nhà phát hành mã thông báo truy cập này [
python AC_client.pypython AC_auth_server.pypython API_server.py74].
python AC_client.pypython AC_auth_server.pypython API_server.py75 là ngày hết hạn của mã thông báo truy cập, được đặt thành
python AC_client.pypython AC_auth_server.pypython API_server.py76 giây [
python AC_client.pypython AC_auth_server.pypython API_server.py77]. Mỗi mã thông báo truy cập trong mẫu này được mã hóa bằng khóa riêng và có thể được giải mã bằng khóa chung tương ứng;
Sử dụng mã thông báo truy cập để truy cập tài nguyên
Sau khi mã thông báo truy cập được nhận và ghi vào cookie, khách hàng có thể sử dụng nó để truy cập máy chủ API
Nguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/client/AC_client. py#L28Như đã nói trước đó, thay vì được nhúng trong cookie, mã thông báo truy cập được chuyển như một phần của tiêu đề Ủy quyền của yêu cầu HTTP
Phương thức
python AC_client.pypython AC_auth_server.pypython API_server.py78 từ
python AC_client.pypython AC_auth_server.pypython API_server.py79 trích xuất mã thông báo truy cập từ tiêu đề và xác minh nó bằng phương thức
python AC_client.pypython AC_auth_server.pypython API_server.py80Nguồn. https. //github. com/michaelawyu/auth-server-sample/blob/master/AC/API_server/auth. py#L9
Chúng tôi cũng sử dụng gói
python AC_client.pypython AC_auth_server.pypython API_server.py9 để xác minh JWT. Nó kiểm tra chữ ký của JWT và đảm bảo rằng giá trị của các trường
python AC_client.pypython AC_auth_server.pypython API_server.py73 và
python AC_client.pypython AC_auth_server.pypython API_server.py75 là hợp lệ. Các trường tùy chỉnh [nếu có] được bao gồm trong mã thông báo đã giải mã và có thể được xác minh thủ côngGhi chú quan trọng
- Vì lý do đơn giản, mẫu này sử dụng kết nối HTTP. Tuy nhiên, trong quá trình triển khai, bạn phải luôn sử dụng HTTPS. Mã nhận xét trong mẫu,
//localhost:5001/auth?response_type=code&client_id=sample-client-id&redirect_url=//localhost:5000/callback
2cho phép các ứng dụng phân phối nội dung qua HTTPS bằng khóa riêng và chứng chỉ tự ký khi chạy cục bộ. Tuy nhiên, có khả năng trình duyệt của bạn sẽ đưa ra cảnh báo khi sử dụng phương pháp này, vì rõ ràng, các chứng chỉ tự ký không thể tin cậy được